home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / berm122 / import.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  87KB  |  3,026 lines

  1. /***************************************************************************
  2.  *  IMPORT.C                                                               *
  3.  *                                                                         *
  4.  *  import utility.                                                        *
  5.  *                                                                         *
  6.  * This program IMPORTs FidoNet<tm> mailpackets and TOSSes mail and        *
  7.  * echomail.                                                               *
  8.  *                                                                         *
  9.  * IMPORT is part of the BERMUDA software. BERMUDA is a package of FidoNet *
  10.  * compatible message/nodelist processing software.                        *
  11.  * Please read LICENSE for information about distribution.                 *
  12.  *                                                                         *
  13.  * Written by Jac Kersing,                                                 *
  14.  * Modifications by Enno Borgsteede and Rinaldo Visscher                   *
  15.  * Modifications by Vincent Pomey and Franck Arnaud                        *
  16.  ***************************************************************************/
  17.  
  18. #define MAILER              /* needed in PANDORA.H */
  19. #define DEBUG   0           /* Debugging mode (extended info) on/off */
  20. #define DEBUG_SORT      0   /* Debugging info in sort routine? */
  21.  
  22. #include "pandora.h"        /* for structure of the area's etc. */
  23. #include "mail.h"           /* pretty obvious if your unpacking mail.. */
  24.  
  25. #include <stdlib.h>
  26.  
  27. #if TC
  28. #include <dos.h>
  29. #include <sys\stat.h>
  30. #endif
  31.  
  32. #define __PROTO__ 1
  33. #include "import.pro"
  34. #include "utextra.pro"
  35.  
  36.  
  37. #define UVERSION "1.22"     /* version-number */
  38. #define LASTMOD  __DATE__
  39.  
  40. #define isBERMUDA 0xA0          /* productcode for Bermuda */
  41.  
  42. #define MSGSCANNED      0x8000
  43.  
  44. /* defines for writemessage         */
  45. #define OUTBOUND    0       /* message to mailarea      */
  46. #define LOCAL       1       /* message to local msgfile */
  47. #define SCANFILE    2       /* message to node file     */
  48.  
  49. /* defines for SEEN-BY treatement   */
  50. #define NOTHING     0       /* no echomail message         */
  51. #define POINTS      1       /* add pointlist to message    */
  52. #define LOCALS      2       /* add local list to msg       */
  53. #define DIFFZONE    4       /* add list for OTHER zone     */
  54. #define OTHERS      8       /* add all nodes already there */
  55.  
  56. struct _passw           /* structure for passwords */
  57. {
  58.   char passw[8];        /* the password itself */
  59.   unsigned zone;        /* zone number for remote */
  60.   unsigned net;         /* net number for remote */
  61.   unsigned node;        /* node number for remote */
  62.   unsigned point;       /* point number for remote */
  63.   int  my_aka;          /* the number in the addresslist for this sucker */
  64.   struct _passw *next;  /* pointer to next struct */
  65. } ;
  66.  
  67. struct _aka
  68. {
  69.  unsigned zone;
  70.  unsigned net;
  71.  unsigned node;
  72.  unsigned point;
  73.  unsigned pointnet;
  74. } ;
  75.  
  76. #undef  NORMAL
  77.  
  78. void Aopen(), Aclose(), cleanEcho(), renumber();
  79.  
  80. char progname[]="B-I";      /* program name for logging */
  81. FILE *pkt;                  /* the mailpacket */
  82. char *Bpath="";             /* path for mailer info */
  83.  
  84. char packet[80];            /* name of the packet we're dealing with now */
  85. struct _pkthdr phdr;        /* storage for packetheader */
  86. struct _pktmsgs mhdr;       /* header of current message */
  87. struct Hdr hhdr;            /* header for message (in hdr file) */
  88. struct Hdr Mhdr;            /* storage for outgoing message header  */
  89.  
  90. char arc_prg[90];           /* archive program name */
  91. char arc_cmd[90];           /* commands for archive program */
  92. #ifdef LINN
  93. char zip_prg[90];
  94. char zip_cmd[90];
  95. char zoo_prg[90];
  96. char zoo_cmd[90];
  97. char lzh_prg[90];
  98. char lzh_cmd[90];
  99. char arj_prg[90];
  100. char arj_cmd[90];
  101. char def_prg[90];           /* default archiver */
  102. char def_cmd[90];
  103. #endif
  104. int  akeep=0;               /* keep extracted archives? */
  105. char *ms;                   /* pointer in message buffer */
  106.  
  107. int  lastarea;              /* area last message was stored */
  108. char *AreaPath[N_AREAS];    /* path to message area                 */
  109. char *AreaName[N_AREAS];    /* name of area                         */
  110. char *AreaOrig[N_AREAS];    /* the origin line for this area        */
  111. int  AreaDays[N_AREAS];     /* number of days this area lasts       */
  112. unsigned *ToZone[N_AREAS];  /* Zone, Net,                           */
  113. unsigned *ToNet[N_AREAS];   /*            Node and Point            */
  114. unsigned *ToNode[N_AREAS];  /*    numbers of nodes we're supposed   */
  115. unsigned *ToPoint[N_AREAS]; /*    to echo messages to..........     */
  116. int  nmsgs[N_AREAS];        /* number of messages tossed to this area */
  117. int  smsgs[N_AREAS];        /* number of messages to sysop in this area */
  118. #ifdef LINN
  119. int  emsgs[N_AREAS];        /* number of messages echoed in this area */
  120. #endif
  121. int  SendTo[51];            /* Send to this node too?               */
  122. unsigned TZone[51];         /* Temp. storage for addresses          */
  123. unsigned TNet[51];          /* Zone and Net..                       */
  124. unsigned TNode[51];         /*               Node                   */
  125. unsigned TPoint[51];        /*                      Point           */
  126.  
  127. unsigned SeenZone[950];     /* Zone...                              */
  128. unsigned SeenNet[950];      /* adress of nodes that have seen       */
  129. unsigned SeenNode[950];     /*                         this message */
  130. unsigned SeenPoint[950];    /*                               Point  */
  131. int  nSeen;                 /* number of Seen-bys                   */
  132. unsigned PathZone[200];     /* Zone of path..                       */
  133. unsigned PathNet[200];      /* adresses listed in the               */
  134. unsigned PathNode[200];     /*                        path line     */
  135. unsigned PathPoint[200];    /* Ditto                                */
  136. int  nPath;                 /* number of nodes in Path              */
  137. char ThisArea[80];          /* name of this echomail area           */
  138.  
  139. int  mailarea;              /* number of mailarea                   */
  140. int  badarea;               /* number of area for badmessages       */
  141. int  msgareas;              /* number of messageareas               */
  142. char *hold;                 /* path to hold area                    */
  143. #ifdef LINN
  144. char *holdbink;
  145. #endif
  146. char *mailpath;             /* path to mailmsgs                     */
  147. char *netpath;              /* path to netmail                      */
  148. struct _aka alias[30];      /* aliases                              */
  149. int  nalias;                /* number of aliases                    */
  150. #ifdef LINN
  151. int  binkley=0;
  152. int  add_aka=0;             /* number of aliases to add to seen-bys */
  153. int  no_intl=0;
  154. #else
  155. int  add_aka;               /* number of aliases to add to seen-bys */
  156. #endif
  157. int  verbose=0;             /* level for message displaying         */
  158. int  loglevel;              /* level for message logging            */
  159. #ifdef LINN
  160. int  killrouted;            /* set flag Kill/Sent for routed msg    */
  161. #endif
  162. char *logname;              /* name of logfile                      */
  163. FILE *log;                  /* filepointer for logfile              */
  164. struct _passw *pwd;         /* password pointer                     */
  165.  
  166. char sysop[80];             /* name of sysop */
  167. char *ourorigin;            /* line for origin                      */
  168. unsigned ourzone;           /* zone,                                */
  169. unsigned ournet;            /*      net and                         */
  170. unsigned ournode;           /*              node of our BBS         */
  171. unsigned ourpoint;          /*                 point                */
  172. unsigned ourpointnet;       /* we've got a pointnet too             */
  173. char ourpwd[10];            /* the password we're using now         */
  174.  
  175. char *MESSAGE;              /* adress of message buffer (malloced)  */
  176. char *mend;                 /* points to end of the message         */
  177. char *endbody;              /* end of message body WITHOUT seen-bys */
  178. int  mlength;               /* length of message (including seen-by)*/
  179. int  area;                  /* area we're processing                */
  180. int  echomsgs=0;            /* number of messages generated         */
  181. char *origl;                /* points to origin line in message     */
  182.  
  183. int  ask=0;                 /* ask for a packetname? */
  184. int  arcmail=0;             /* unpacking arcmail? */
  185. int  use_path;              /* do we wanna use the PATH line?       */
  186. int  use_kludge;            /* we want to use the IFNA kludge?      */
  187. int  use_origin;            /* do we wanna have an origin line??    */
  188. int  use_readdress;         /* readress message (fake from our bbs) */
  189. int  use_packet;            /* scan messages to packets             */
  190. int  use_tiny=0;            /* tiny adresses (ones I'm sending to)  */
  191. int  secure=0;              /* only import mail from known sources  */
  192.  
  193. FILE *MHDR;
  194. FILE *MMSG;
  195. FILE *hdr;                  /* file with message headers */
  196. FILE *msg;                  /* file with message text */
  197.  
  198. char oldmsg[80];            /* names of the message and header files */
  199. char oldhdr[80];
  200.  
  201. int  j;                     /* stupid counter                       */
  202. int  x;                     /* x position in line                   */
  203.  
  204. unsigned pktzone[10];       /* zone, net, node and point            */
  205. unsigned pktnet[10];        /* = address for open packet            */
  206. unsigned pktnode[10];       /* used for saving messages to          */
  207. unsigned pktpoint[10];
  208. unsigned pktfake[10];
  209. unsigned fromzone;          /* address this packet was packed       */
  210. unsigned fromnet;
  211. unsigned fromnode;
  212. unsigned frompoint;
  213. FILE *pktfile[10];          /* the packet                           */
  214.  
  215. /* Ok, so far all definitions. The program is next.. */
  216.  
  217. char *skip_blanks(string)
  218. char *string;
  219. {
  220.     while (*string && isspace(*string)) ++string;
  221.     return string;
  222. }
  223.  
  224. char *skip_to_blank(string)
  225. char *string;
  226. {
  227.         while (*string && !isspace(*string)) ++string;
  228.         return string;
  229. }
  230.  
  231. char *myalloc(sp)
  232. size_t sp;
  233. {
  234.     char *tmp;
  235.     
  236.     if (sp==0) sp=1;
  237.     tmp=malloc(sp);
  238.     if (tmp==NULL)
  239.     {
  240.         message(6,"!Mem error");
  241.         exit(1);
  242.     }
  243.     return tmp;
  244. }
  245.  
  246. char *ctl_string(string)
  247. char *string;
  248. {
  249.     char *p, *d;
  250.     p=skip_blanks(string);
  251.     d=myalloc(strlen(p)+1);
  252.     strcpy(d,p);
  253.     return d;
  254. }
  255.  
  256. char *ctl_path(str)
  257. char *str;
  258. {
  259.     char *q;
  260.     
  261.     str= skip_blanks(str);
  262.     for (q=str; *q && !isspace(*q); q++) ;
  263.     *q= '\0';
  264. #if UNIX
  265.     if (*(q-1)!='/') strcat(q,"/");
  266. #else
  267.     if (*(q-1)!='\\') strcat(q,"\\");
  268. #endif
  269.     return ctl_string(str);
  270. }
  271.  
  272. char *ctl_file(str)
  273. char *str;
  274. {
  275.     char *q;
  276.     
  277.     str= skip_blanks(str);
  278.     for (q=str; *q && !isspace(*q); q++) ;
  279.     *q= '\0';
  280.     return ctl_string(str);
  281. }
  282.  
  283. int init_conf()
  284. {
  285.     FILE *conf;                     /* filepointer for config-file */
  286.     char buffer[256];               /* buffer for 1 line */
  287.     char *p;                        /* workhorse */
  288. #ifdef LINN
  289.     char *q;                        /* another one */
  290. #endif
  291.     int count;                      /* just a counter... */
  292.     char *ffirst();                 /* directory find */
  293.     char *getenv();                 /* get the environment string */
  294.  
  295.     p=getenv("MAILER");
  296.     if (!ffirst("bermuda.cfg") &&      /* check local config */
  297.         !ffirst("tb.cfg") &&
  298.         p!=NULL && *p!='\0')
  299.     {                                   /* no local, and envi contained one */
  300.         Bpath= ctl_path(p);
  301.     }
  302.  
  303.     sprintf( buffer, "%sbermuda.cfg", Bpath);
  304.     conf= fopen(buffer, "r");
  305.  
  306.     if (conf==NULL)
  307.     {
  308.         sprintf(buffer,"%stb.cfg", Bpath);
  309.  
  310.         conf = fopen(buffer, "r");
  311.     }
  312.  
  313.  
  314.     if (verbose > 2) printf("Config: %s\n",buffer);
  315.  
  316.     if (conf==NULL)
  317.     {
  318.         message(6,"!Configuration file not found, please check!!!");
  319.         return 1;                           /* not found, back */
  320.     }
  321.  
  322.     /* set all to default values */
  323.     
  324.     loglevel=255;
  325.     ourzone=ournet=ournode=ourpoint=0;
  326. #ifdef LINN
  327.     killrouted=1;
  328. #endif
  329.     
  330.     message(-1,"+Parsing configuration file");
  331.        
  332.     while((fgets(buffer, 250, conf)))       /* read a line */
  333.     {
  334.         if (verbose > 2) printf("Config: %s\n",buffer);
  335.  
  336.         p=skip_blanks(buffer);
  337.         if (*p==';') continue;               /* comment?? */
  338.  
  339.         /* delete ALL chars following (and inclusive) comment sign */
  340.         if ((p=strchr(buffer,';'))!=NULL)  *p= '\0';
  341.         if ((count= (int)strlen(buffer))<3) continue;
  342.                                             /* what's the length of the rest? */
  343.         p= &buffer[--count];
  344.         if (*p=='\n') *p=0;                 /* delete (possible) newline char */
  345.  
  346. #ifdef LINN
  347.         /* process "application bermuda" lines as normal lines */
  348.         if (!strnicmp(buffer,"application",11))
  349.         {
  350.             p=skip_blanks(&buffer[11]);
  351.             if(!strnicmp(p,"bermuda",7)) {
  352.                 p=skip_blanks(&p[7]);
  353.                 strcpy(buffer,p);
  354.             }
  355.         }
  356. #endif
  357.  
  358.         if (!strnicmp(buffer,"sysop",5))
  359.         {
  360.                 p=skip_blanks(&buffer[5]);
  361.                 strncpy(sysop,p,79);
  362.                 sysop[79]='\0';
  363.                 continue;
  364.         }
  365.  
  366.         if (!strnicmp(buffer,"address",7))
  367.         {
  368.             p=skip_blanks(&buffer[7]);
  369.             if(getaddress(p,&alias[nalias].zone, &alias[nalias].net,
  370.                 &alias[nalias].node, &alias[nalias].point)!=7)
  371.             {
  372.                message(3,"!Invalid address in %s",buffer);
  373.                continue;
  374.             }
  375.             p=skip_blanks(skip_to_blank(p));
  376.  
  377.             if (*p=='+' || *p=='*') p=skip_blanks(skip_to_blank(p));
  378.  
  379.             if (*p && isdigit(*p))            {
  380.                 if ((alias[nalias].pointnet=atoi(p))==0)
  381.                 {
  382.                    message(6,"!Invalid pointnet in %s",buffer);
  383.                    continue;
  384.                 }
  385.             }
  386.             else alias[nalias].pointnet=0;
  387.             ++nalias;
  388.  
  389.             ourzone=alias[0].zone;
  390.             ournet=alias[0].net;
  391.             ournode=alias[0].node;
  392.             ourpoint=alias[0].point;
  393.             ourpointnet=alias[0].pointnet;
  394.  
  395.             continue;
  396.         }
  397.  
  398.         if (!strnicmp(buffer,"loglevel",8))
  399.         {
  400.             p=skip_blanks(&buffer[8]);
  401.             if (sscanf(p,"%d", &count)!=1 || count>6 || count<0)
  402.                 message(3,"-Invalid loglevel (%s)", p);
  403.             else loglevel=count;
  404.             continue;
  405.         }
  406.  
  407.         if (!strnicmp(buffer, "statuslog",9))
  408.         {
  409.             logname= ctl_string(&buffer[9]);
  410.             if ((log=fopen(logname, "a"))==NULL)
  411.                 if ((log=fopen(logname, "w+"))==NULL)
  412.                 {
  413.                     message(6,"!Could not create logfile!");
  414.                     free(logname);
  415.                     logname=NULL;
  416.                 }
  417.             else
  418.             {
  419.                 fflush(log);
  420.             }
  421.             continue;
  422.         }
  423.  
  424.         if (!strnicmp(buffer,"netfile",7))
  425.         {
  426.             mailpath=ctl_path(&buffer[7]);
  427.             continue;
  428.         }
  429.  
  430.         if (!strnicmp(buffer,"netmail",7))
  431.         {
  432.             netpath=ctl_string(&buffer[7]);
  433.             continue;
  434.         }
  435.  
  436.         if (!strnicmp(buffer,"hold",4))
  437.         {
  438.             hold=ctl_path(&buffer[4]);
  439. #ifdef LINN
  440.             holdbink=strdup(hold); holdbink[strlen(holdbink)-1]=0;
  441. #endif
  442.             continue;
  443.         }
  444.  
  445.         if (!strnicmp(buffer,"key",3))
  446.         {
  447.             parsekey(&buffer[3]);
  448.             continue;
  449.         }
  450.  
  451. #ifdef LINN
  452.     if (!strnicmp(buffer,"nokillrouted",12))
  453.     {
  454.         killrouted = 0;
  455.         continue;
  456.     }
  457.  
  458.     if (!strnicmp(buffer,"arcunpack", 9))
  459.     {
  460.         p=skip_blanks(&buffer[9]);
  461.             q=p;
  462.             while (*q && !isspace(*q)) ++q;
  463.             *q='\0';
  464.         strcpy (arc_prg, p);
  465.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  466.             strcpy (arc_cmd, p);
  467.         continue;
  468.     }
  469.  
  470.     if (!strnicmp(buffer,"zipunpack", 9))
  471.     {
  472.         p=skip_blanks(&buffer[9]);
  473.             q=p;
  474.             while (*q && !isspace(*q)) ++q;
  475.             *q='\0';
  476.         strcpy (zip_prg, p);
  477.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  478.             strcpy (zip_cmd, p);
  479.         continue;
  480.     }
  481.  
  482.     if (!strnicmp(buffer,"zoounpack", 9))
  483.     {
  484.         p=skip_blanks(&buffer[9]);
  485.             q=p;
  486.             while (*q && !isspace(*q)) ++q;
  487.             *q='\0';
  488.         strcpy (zoo_prg, p);
  489.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  490.             strcpy (zoo_cmd, p);
  491.         continue;
  492.     }
  493.  
  494.     if (!strnicmp(buffer,"lzhunpack", 9))
  495.     {
  496.         p=skip_blanks(&buffer[9]);
  497.             q=p;
  498.             while (*q && !isspace(*q)) ++q;
  499.             *q='\0';
  500.         strcpy (lzh_prg, p);
  501.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  502.             strcpy (lzh_cmd, p);
  503.         continue;
  504.     }
  505.  
  506.     if (!strnicmp(buffer,"arjunpack", 9))
  507.     {
  508.         p=skip_blanks(&buffer[9]);
  509.             q=p;
  510.             while (*q && !isspace(*q)) ++q;
  511.             *q='\0';
  512.         strcpy (arj_prg, p);
  513.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  514.             strcpy (arj_cmd, p);
  515.         continue;
  516.     }
  517.  
  518.     if (!strnicmp(buffer,"defaultunpack", 13))
  519.     {
  520.         p=skip_blanks(&buffer[13]);
  521.             q=p;
  522.             while (*q && !isspace(*q)) ++q;
  523.             *q='\0';
  524.         strcpy (def_prg, p);
  525.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  526.             strcpy (def_cmd, p);
  527.         continue;
  528.     }
  529.  
  530.     if (!strnicmp(buffer,"binkley", 7))
  531.     {
  532.         binkley=1;
  533.         continue;
  534.     }
  535. #endif
  536.  
  537.     }
  538.     
  539.     fclose(conf);
  540.     
  541.     return 0;                           /* signal OK */
  542. }
  543.  
  544. void parsekey(p)
  545. char *p;
  546. {
  547.     int i;
  548.     char password[9];
  549.     struct _passw *pw,*pn;
  550.     unsigned zone,net,node,point;
  551.     int my_aka=0;
  552.     
  553.     /* get to the end of the list. */
  554.     pw=pwd;
  555.  
  556.     while (pw->next!=NULL)      pw=pw->next;
  557.  
  558.     password[0]='\0';
  559.     
  560.     p=skip_blanks(p);
  561.     while (*p && *p!=';')
  562.     {
  563.         if (*p=='!')
  564.         {
  565.             strncpy(password,p+1,7);
  566.             for (i=0; i<7; ++i)
  567.             {
  568.                 if (isspace(password[i])) break;
  569.             }
  570.             password[i]='\0';
  571.  
  572.             /* skip password and go on to node(s) */
  573.             p=skip_to_blank(p);
  574.             p=skip_blanks(p);
  575.             continue;
  576.         }
  577.  
  578.         if (*p=='#')
  579.         {
  580.             if (getaddress(p+1,&zone,&net,&node,&point))
  581.             {
  582.                 int found=0;
  583.                 for (i=0; i<nalias; i++)
  584.                 {
  585.                     if (alias[i].zone==zone && alias[i].net==net &&
  586.                         alias[i].node==node && alias[i].point==point)
  587.                     {
  588.                         found++;
  589.                         break;
  590.                     }
  591.                 }
  592.                 if (found) my_aka=i;
  593.                 else
  594.                 {
  595.                     my_aka=0;
  596.                     message(3,"-Address %d:%d/%d.%d used in key is unknown",
  597.                      zone,net,node,point);
  598.                 }
  599.             }
  600.  
  601.             p= skip_to_blank(p);
  602.             p= skip_blanks(p);
  603.             continue;
  604.         }
  605.  
  606.         pn=pw->next= (struct _passw *) myalloc(sizeof(struct _passw));
  607.  
  608.         if (!getaddress(p,&zone,&net,&node,&point))
  609.         {
  610.             free(pn);
  611.             pw->next=NULL;
  612.             message(3,"-Invalid address: %s",p);
  613.             return;
  614.         }
  615.  
  616.         if (point)
  617.         {
  618.             for (i=0; i < nalias; i++)
  619.             {
  620.                 if (alias[i].zone==zone && alias[i].net==net &&
  621.                     alias[i].node==node)
  622.                 {
  623.                     net= alias[i].pointnet;
  624.                     node= point;
  625.                     point= 0;
  626.                     break;
  627.                 }
  628.             }
  629.         }
  630.         pn->zone=zone;
  631.         pn->net=net;
  632.         pn->node=node;
  633.         pn->point=point;
  634.         pn->my_aka=my_aka;
  635.         strcpy(pn->passw,password);
  636.         p=skip_to_blank(p);
  637.         p=skip_blanks(p);
  638.         pw=pn;
  639.         pw->next=NULL;
  640.     }
  641.     
  642.     return;
  643. }
  644.  
  645. int getint(p,i)                                   /* Mind the calling parms! */
  646. char **p;
  647. unsigned *i;
  648. {
  649.         char *q;
  650.         long temp;
  651.  
  652.         q=*p;
  653.         if (!isdigit(*q)) return (-1);
  654.  
  655.         temp=0;
  656.         do {
  657.            temp*=10;
  658.            temp+=(*q++-'0');
  659.            } while (isdigit(*q));
  660.         *p=q;
  661.         *i=(int)temp;
  662.         if (temp>32767) return (-1);
  663.         return (0);
  664. }
  665.  
  666. int getaddress(str, zone, net, node, point)     /* Decode zz:nn/mm.pp number */
  667. char *str;       /* 0=error | 1=node | 2=net/node | 3=zone:net/node | 4=pnt */
  668. unsigned *zone, *net, *node, *point;
  669. {
  670.         int retcode=0;
  671.  
  672.         *zone  = alias[0].zone;
  673.         *net   = alias[0].net;
  674.         *node  = alias[0].node;
  675.         *point = 0;
  676.  
  677.         str=skip_blanks(str);
  678.  
  679.         if (*str=='.') goto pnt;
  680.         retcode++;
  681.         if (getint(&str,node))
  682.         {
  683.             if (strnicmp(str,"ALL",3)) return (0);
  684.             *zone=*net=*node=65535U;
  685.             return 10;
  686.         }
  687.         if (!*str) return (retcode);
  688.         if (*str=='.') goto pnt;
  689.         retcode++;
  690.         if (*str==':') {
  691.            str++;
  692.            *zone=*node;
  693.            *node=65535U;
  694.            if (!*str) return (0);
  695.            if (getint(&str,node))
  696.            {
  697.               if (strnicmp(str,"ALL",3)) return (0);
  698.               *net=*node=65535U;
  699.               return 10;
  700.            }
  701.            retcode++;
  702.         }
  703.         if (*str!='/') return (0);
  704.         str++;
  705.         *net=*node;
  706.         *node=alias[0].node;
  707.         if (getint(&str,node))
  708.         {
  709.             if (strnicmp(str,"ALL",3)) return (0);
  710.             *node=65535U;
  711.             return 10;
  712.         }
  713.         if (*str=='.') goto pnt;
  714.         return (retcode);
  715. pnt:    str++;
  716.         if (getint(&str,point))
  717.         {
  718.             if (strnicmp(str,"ALL",3)) return (0);
  719.             *point=65535U;
  720.             return 10;
  721.         }
  722.         return (4+retcode);
  723. }
  724.  
  725. int getalias(zone,net,node,point)
  726. unsigned zone,net,node,point;
  727. {
  728.     int i;
  729.     struct _passw *pw;
  730.     
  731.     pw=pwd->next;
  732.     
  733.     if (point)
  734.     {
  735.         for (i=0; i < nalias; i++)
  736.         {
  737.             if (alias[i].zone==zone && alias[i].net==net &&
  738.                alias[i].node==node && alias[i].point==0)
  739.             {
  740.                 net= alias[i].pointnet;
  741.                 node= point;
  742.                 point= 0;
  743.                 break;
  744.             }
  745.         }
  746.     }
  747.  
  748.     while (pw!=NULL)
  749.     {
  750.        /* no match at all.. (yet) */
  751.         if ((pw->zone==65535U || pw->zone==zone) &&
  752.        /* zone numbers match, now net */
  753.            (pw->net==65535U || pw->net==net) &&
  754.        /* zone and net match.. node also? */
  755.            (pw->node==65535U || pw->node==node) &&
  756.        /* and how about point */
  757.            (pw->point==65535U || pw->point==point))
  758.         {
  759.                 ourzone=alias[pw->my_aka].zone;
  760.                 ournet=alias[pw->my_aka].net;
  761.                 ournode=alias[pw->my_aka].node;
  762.                 ourpoint=alias[pw->my_aka].point;
  763.                 ourpointnet=alias[pw->my_aka].pointnet;
  764.                 return 1;
  765.         }
  766.         pw=pw->next;
  767.     }
  768.     ourzone=alias[0].zone;
  769.     ournet=alias[0].net;
  770.     ournode=alias[0].node;
  771.     ourpoint=alias[0].point;
  772.     ourpointnet=alias[0].pointnet;
  773.     return 0;
  774. }
  775.  
  776. void get_passw(zone,net,node,point)
  777. unsigned zone,net,node,point;
  778. {
  779.     int i;
  780.     struct _passw *pw;
  781.     
  782.     pw=pwd->next;
  783.     
  784.     if (point)
  785.     {
  786.         for (i=0; i < nalias; i++)
  787.         {
  788.             if (alias[i].zone==zone && alias[i].net==net &&
  789.                 alias[i].node==node && alias[i].point==0)
  790.             {
  791.                 net= alias[i].pointnet;
  792.                 node= point;
  793.                 point= 0;
  794.                 break;
  795.             }
  796.         }
  797.     }
  798.   
  799.     while (pw!=NULL)
  800.     {
  801.         /* vp 27 juil 93 : no wildcards for passwords */
  802.        /* no match at all.. (yet) */
  803.         if ((/*pw->zone==65535U ||*/ pw->zone==zone) &&
  804.        /* zone numbers match, now net */
  805.            (/*pw->net==65535U ||*/ pw->net==net) &&
  806.        /* zone and net match.. node also? */
  807.            (/*pw->node==65535U ||*/ pw->node==node) &&
  808.        /* and how about point */
  809.            (/*pw->point==65535U ||*/ pw->point==point))
  810.         {
  811.                 strcpy(ourpwd,pw->passw);
  812.                 return;
  813.         }
  814.         pw=pw->next;
  815.     }
  816.     *ourpwd= '\0';
  817. }
  818.  
  819. void init(argc, argv)            /* initialize everything needed */
  820. int argc;                   /* counter */
  821. char *argv[];               /* commandline crap */
  822. {
  823.     int i,j;                /* counter */
  824.     char *p, *q;            /* nice pointers.. */
  825.     char buffer[300];       /* to store lines from AREAS.BBS etc. in */
  826.     char temp[80];          /* temp. storage */
  827.     char areasbbs[80];      /* name of file for AREAS.BBS */
  828.     int  the_box=0;         /* flags to signal call from The-Box */
  829.     FILE *fd;               /* file descriptor for control and areas.bbs */
  830. #ifndef LINN
  831.     long atol();
  832. #endif
  833.     
  834.     strcpy(areasbbs, "areas.bbs");  /* default name */
  835. #ifdef LINN
  836.     /* set all archiver to nothing, except default archiver to ARC */
  837.     /* arc.ttp should be actually whatarc.ttp */
  838.     lzh_prg[0] = '\0';
  839.     arj_prg[0] = '\0';
  840.     zoo_prg[0] = '\0';
  841.     zip_prg[0] = '\0';
  842.     arc_prg[0] = '\0';
  843. #if     STTC
  844.     strcpy(def_prg,"ARC.TTP");
  845. #endif
  846. #if     TC
  847.     strcpy(def_prg,"ARC.EXE");
  848. #endif
  849.     strcpy (def_cmd, "X");
  850. #else
  851. #if     STTC
  852.     strcpy(arc_prg,"ARC.TTP");
  853. #endif
  854. #if     TC
  855.     strcpy(arc_prg,"ARC.EXE");
  856. #endif
  857.     strcpy(arc_cmd,"X");
  858. #endif
  859.     strcpy(areasbbs, "areas.bbs");  /* default name */
  860.  
  861.     pwd= (struct _passw *) myalloc(sizeof(struct _passw));
  862.     pwd->zone=pwd->net=pwd->node=pwd->point=0;
  863.     pwd->next=NULL;
  864.  
  865.     if (init_conf()) exit(2);       /* first parse config file */
  866.     
  867.     use_path=use_origin=use_readdress=1;
  868.     use_kludge=0;
  869.  
  870.     for (i=1;i<argc;i++)
  871.     {
  872.         ++argv;
  873.  
  874.         if (argv[0][0]=='-')
  875.         {
  876.             switch(toupper(argv[0][1]))
  877.             {
  878.               case 'S': ask=1; break;     /* ask for packetnames     */
  879.               case 'R': secure++; break;  /* secure system  */
  880.               case 'K': ++akeep;   break; /* keep extracted archives */
  881.               case 'P': use_packet=1; break; /* output to packet */
  882.               case 'I': use_kludge=1; break; /* ifna kludge */
  883.               case 'V': verbose++;    break; /* more detail */
  884.               case 'G': use_path=0;   break; /* no path line */
  885.               case 'T': ++the_box;    break; /* called with logging */
  886. #ifdef LINN
  887.               case 'D': add_aka = nalias; break;
  888.               case 'N': no_intl = 1;
  889.          /* -A set the default archiver, since arc_??? now means
  890.                 only the ARC program */
  891.               case 'A': *def_cmd= *def_prg= '\0';
  892.                         if (i+1<argc)
  893.                         {
  894.                             strncpy(def_prg,argv[1],89);
  895.                             while (++i<argc-1 &&
  896.                               (strlen(def_cmd)+strlen(argv[1]))<88)
  897.                             {
  898.                                 strcat(def_cmd,(++argv)[1]);
  899.                                 strcat(def_cmd," ");
  900.                             }
  901.                         }
  902.                         break;
  903. #else
  904.               case 'A': *arc_cmd= *arc_prg= '\0';
  905.                         if (i+1<argc)
  906.                         {
  907.                             strncpy(arc_prg,argv[1],89);
  908.                             while (++i<argc-1 &&
  909.                               (strlen(arc_cmd)+strlen(argv[1]))<88)
  910.                             {
  911.                                 strcat(arc_cmd,(++argv)[1]);
  912.                                 strcat(arc_cmd," ");
  913.                             }
  914.                         }
  915.                         break;
  916. #endif
  917.               default : message(6,"!Unknown option %s",argv[0]);
  918.             }
  919.         }
  920.         else strcpy(areasbbs,argv[0]);
  921.     }
  922.  
  923.     badarea= mailarea= -1;
  924.     msgareas=0;
  925.  
  926.     sprintf(buffer,"%s%s", Bpath, areasbbs);
  927.     if((fd=fopen(buffer, "r"))==NULL)
  928.     {
  929.         message(0,"=%s not found, assuming simple set-up",buffer);
  930.     }
  931.     else
  932.     {
  933.             /* get the MAIN origin line */
  934.         do
  935.             fgets(buffer,299,fd);
  936.         while (buffer[0]=='-' || buffer[0]==';') ;
  937.  
  938.         q=buffer+strlen(buffer)-1;
  939.         while (isspace(*q) || !*q) *q--=0;  /* get rid of trailing blanks   */
  940.         ourorigin=ctl_string(buffer);
  941.  
  942.         while (fgets(buffer,299,fd))        /* next line                    */
  943.         {
  944.             q=skip_blanks(buffer);
  945.             if (!*q || *q==';') continue;               /* comment line? */
  946.             if (strlen(q)<5) continue;
  947.             if (*q=='-')
  948.             {
  949.                     switch (toupper(*(q+1)))
  950.                     {
  951.                      case 'O': q=skip_to_blank(q);
  952.                                q=skip_blanks(q);
  953.                                p= q+strlen(q)-1;
  954.                                while (isspace(*p) || !*p) *p--=0;
  955.                                AreaOrig[msgareas]=ctl_string(q);
  956.                                break;
  957.                     }
  958.                     continue;
  959.             }
  960.             for (p=temp; *q && !isspace(*q); *p++=*q++) ;
  961.             *p=0;
  962.             AreaPath[msgareas]=ctl_string(temp);        /* copy path to area */
  963.             while (isspace(*q)) q++;
  964.             for (p=temp; *q && !isspace(*q); *p++=*q++) ;
  965.             *p=0;
  966.             AreaName[msgareas]=ctl_string(temp);        /* copy name of area */
  967.             while (*q && !isspace(*q)) q++;
  968.             if (!stricmp(AreaName[msgareas],"MAIL"))
  969.             {                                           /* is the mail area? */
  970.                 mailarea=msgareas;
  971.                 if (mailarea != -1) free(AreaName[mailarea]);
  972.                 AreaName[mailarea]=ctl_string("* Network");
  973.             }
  974.             if (!stricmp(AreaName[msgareas],"BADMSGS"))
  975.             {
  976.                 badarea=msgareas;
  977.                 AreaName[badarea]=ctl_string("* BAD *");
  978.             }
  979.  
  980.             i=1;                            /* No destinations (yet)        */
  981.  
  982.             do
  983.             {                               /* get them all                 */
  984.                 q=skip_blanks(q);
  985.                 j= getaddress(q, &TZone[i], &TNet[i], &TNode[i], &TPoint[i]);
  986.                 if (j==0) break;
  987.                 if (j==10)
  988.                 {
  989.                     message(6,"!Invalid address %s in area-file",q);
  990.                     exit(2);
  991.                 }
  992.                 while (*q && !isspace(*q)) q++;
  993.                 i++;
  994.             }
  995.             while (*q);
  996.             TZone[0]=TZone[1];
  997.             TNet[0]=TNet[1];
  998.             TNode[0]=TNode[1];
  999.             TPoint[0]=TPoint[1];
  1000.  
  1001.             --i;
  1002.             SortThem(&TZone[1],&TNet[1],&TNode[1],&TPoint[1],&i,0);
  1003.             ++i;
  1004.             TZone[i]=TNet[i]=TNode[i]=TPoint[i]=0; /* and terminate         */
  1005.             ++i;
  1006.  
  1007.             /* only store them if we found some and if it's not the bad area */
  1008.             if (i>2 && msgareas != badarea)
  1009.             {
  1010.                 ToZone[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i);
  1011.                 ToNet[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i);
  1012.                 ToNode[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i);
  1013.                 ToPoint[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i);
  1014.                 memmove(ToZone[msgareas],TZone,sizeof(unsigned) * i);
  1015.                 memmove(ToNet[msgareas],TNet,sizeof(unsigned) * i);
  1016.                 memmove(ToNode[msgareas],TNode,sizeof(unsigned) * i);
  1017.                 memmove(ToPoint[msgareas],TPoint,sizeof(unsigned) * i);
  1018.             }
  1019.  
  1020.             if (verbose > 2)
  1021.             {
  1022.                 print("%s %s",AreaPath[msgareas],AreaName[msgareas]);
  1023.                 if (i>2 && msgareas!=badarea)
  1024.                     for(i=0;ToNet[msgareas][i];i++)
  1025.                       print(" %u/%u",ToNet[msgareas][i],
  1026.                        ToNode[msgareas][i]);
  1027.                 print("\n");
  1028.             }
  1029.  
  1030.             if (AreaOrig[msgareas]==NULL) AreaOrig[msgareas]=ourorigin;
  1031.  
  1032.             ++msgareas;                     /* next area                    */
  1033. #ifdef LINN
  1034.         if (msgareas==N_AREAS-2) {
  1035.             message(6,"!More than %d areas, areas.bbs read incomplete", N_AREAS);
  1036.             break;
  1037.         }
  1038. #endif
  1039.         }
  1040.         fclose(fd);
  1041.     }
  1042.  
  1043.     if (mailarea==-1 && netpath)       /* if mailarea not defined in AREAS.BBS */
  1044.     {
  1045.         AreaName[msgareas]=ctl_string("* Network");
  1046.         AreaPath[msgareas]=ctl_string(netpath);
  1047.         mailarea=msgareas++;            /* then use the THE-BOX.CFG one */
  1048.     }
  1049.  
  1050. #ifdef LINN
  1051.     for(i=0;i<msgareas;i++)
  1052.         nmsgs[i]=smsgs[i]=emsgs[i]=0;
  1053. #endif
  1054.     
  1055.     if (mailarea==-1 || !AreaPath[mailarea] || !*AreaPath[mailarea])
  1056.     {
  1057.         message(6,"!Don't know the path to your mailarea..");
  1058.         exit(2);
  1059.     }
  1060.  
  1061.     if (badarea == -1)
  1062.     {
  1063.         /* area for bad messages has not been specified, make it same as mail */
  1064.         badarea = mailarea;
  1065.     }
  1066.  
  1067.     if ((MESSAGE=malloc(30*1024))==NULL)
  1068.     {
  1069.         message(6,"!Mem error");
  1070.         exit(-39);
  1071.     }
  1072.  
  1073.     if (!the_box) loglevel=255;     /* called from command-line, no logging */
  1074.  
  1075.     sprintf(buffer,"%s.MSG",AreaPath[mailarea]);
  1076.     if((MMSG=fopen(buffer, BRUP))==NULL) MMSG=fopen(buffer, BWUP);
  1077.     sprintf(buffer,"%s.HDR",AreaPath[mailarea]);
  1078.     if((MHDR=fopen(buffer, BRUP))==NULL) MHDR=fopen(buffer, BWUP);
  1079.     if (!MMSG || !MHDR)
  1080.     {
  1081.         message(6,"!Error opening Mail file");
  1082.         exit(1);
  1083.     }
  1084.     
  1085.     fseek(MHDR,0l,2);               /* seek to end of (new) mailfile    */
  1086.     fseek(MMSG,0l,2);               /* to add echomail there            */
  1087.  
  1088.     lastarea=-1;                    /* don't lose msgs in area 0 */
  1089.  
  1090.     if (verbose > 1)
  1091.     {
  1092.         print("Mail area (%d): %s\n",mailarea,AreaPath[mailarea]);
  1093.         print("Bad area (%d): %s\n",badarea,AreaPath[badarea]);
  1094.     }
  1095. }
  1096.  
  1097. #ifdef LINN
  1098. int extract(archive)
  1099. char *archive;
  1100. {
  1101.     FILE *amail;
  1102.     char name[80], buffer2[80];
  1103.     char *archiver, *comline, *buf;
  1104.     unsigned char c1, c2, c3, c4;
  1105.     int net;
  1106.  
  1107.      sprintf (name, "%s%s", mailpath, archive);
  1108.     amail = fopen(name, "rb");
  1109.     
  1110.     if (amail == NULL) {
  1111.         return (1);
  1112.     }
  1113.  
  1114.     c1 = fgetc(amail);
  1115.     c2 = fgetc(amail);
  1116.     c3 = fgetc(amail);
  1117.     c4 = fgetc(amail);
  1118.     fclose (amail);
  1119.  
  1120.     archiver = NULL;
  1121.     comline = NULL;
  1122.     
  1123.     if ((c1 == 'P') && (c2 == 'K')) { /* zip mail */
  1124.         message(2, "+Received zipmail");
  1125.         archiver = zip_prg;
  1126.         comline = zip_cmd;
  1127.     }
  1128.  
  1129.     if (c1 == 0x1a) { /* arc mail */
  1130.         message(2, "+Received arcmail");
  1131.         archiver = arc_prg;
  1132.         comline = arc_cmd;
  1133.     }
  1134.     
  1135.     if ((c3 == '-') && (c4 == 'l')) { /* lzh mail */
  1136.         message(2, "+Received lzhmail");
  1137.         archiver = lzh_prg;
  1138.         comline = lzh_cmd;
  1139.     }
  1140.  
  1141.     if ((c1 == 'Z') && (c2 == 'O') && (c3 == 'O')) { /* zoo mail */
  1142.         message(2, "+Received zoomail");
  1143.         archiver = zoo_prg;
  1144.         comline = zoo_cmd;
  1145.     }
  1146.  
  1147.     if ((c1 == 0x60) && (c2 == 0xea)) { /* arj mail */
  1148.         message(2, "+Received arjmail");
  1149.         archiver = arj_prg;
  1150.         comline = arj_cmd;
  1151.     }
  1152.  
  1153.     if ((archiver == NULL) || (*archiver == '\0')) {
  1154.         /* unknown archive type or uninitialized xxx_prg */
  1155.         message(2, "+Received compressed mail");
  1156.         archiver = def_prg;
  1157.         comline = def_prg;
  1158.     }
  1159.  
  1160.         /* set up the command line for archiver */
  1161.     buf=buffer2+1;    /* copy to buffer2 the command line */
  1162.         while (*comline != '\0') {
  1163.             if (*comline != '%')
  1164.                 *buf++ = *comline++;
  1165.             else {
  1166.                 switch (*++comline) {
  1167.                     case 'd' : /* %d = directory */
  1168.                        strcpy (buf, mailpath);
  1169.                            buf = &buf[strlen(buf)];
  1170.                            break;
  1171.                     case 'n' : /* %n = archive name */
  1172.                        strcpy (buf, mailpath);
  1173.                            strcat (buf, archive);
  1174.                            buf = &buf[strlen(buf)];
  1175.                            break;
  1176.                        case '%' : *buf++ = *comline;
  1177.                               break;
  1178.                        case ':' : *buf++ = ';';
  1179.                               break;
  1180.                 }
  1181.                 if (*comline != '\0')
  1182.                     comline++;
  1183.             }
  1184.     }
  1185.         *buf='\0';
  1186.         *buffer2=strlen((buffer2+1));
  1187.  
  1188.         if (verbose > 2) print(" Exec: <%s> <%s>\n", archiver, buffer2);
  1189.  
  1190.         /* and execute it... */
  1191.         net=execute(archiver, buffer2);
  1192.  
  1193.         if (verbose > 2) print("Arc terminated with errorlevel %d\n",net);
  1194.         return (net);    
  1195. }
  1196. #endif
  1197.  
  1198. int process_arc()
  1199. {
  1200.     char buffer1[80], buffer2[140];
  1201.     char *found;
  1202.     char *ffirst(), *fnext();
  1203.     int  net, node;
  1204.     
  1205.     sprint(buffer1, "%s*.*", mailpath);
  1206.  
  1207.     found= ffirst(buffer1);
  1208.     if (!found) return 0;
  1209.     do
  1210.     {
  1211.         if ( is_arcmail(found,(int)strlen(found)-1) )
  1212.         {
  1213.             /* Found an arcmail packet right now! */
  1214.             sscanf( found, "%04x%04x", &net, &node);
  1215.          
  1216. #ifdef LINN
  1217.             net=extract(found);
  1218. #else
  1219.             message(3,"+Received arcmail");
  1220.             /* set up the command line for archiver */
  1221.             sprint((buffer2+1), "%s %s%s %s*.*", arc_cmd, mailpath,
  1222.                    found, mailpath);
  1223.             *buffer2=strlen((buffer2+1));
  1224.  
  1225.             if (verbose > 2) print(" Exec: <%s> <%s>\n", arc_prg, buffer2);
  1226.  
  1227.             /* and execute it... */
  1228.             net=execute(arc_prg, buffer2);
  1229.  
  1230.             if (verbose > 2) print("Arc terminated with errorlevel %d\n",net);
  1231. #endif
  1232.  
  1233.             if (!net)
  1234.             {
  1235.                 sprint(buffer1, "%s%s", mailpath, found);
  1236.                 if (akeep)
  1237.                 {
  1238.                     sprint(buffer2, "%s%11.11s%c", mailpath, found,
  1239.                         *(found+11) + 'A');
  1240.                     if (rename(buffer1,buffer2))
  1241.                     {
  1242.                         message(6,"!Can not rename %s to %s",buffer1,
  1243.                                 buffer2);
  1244.                         exit(2);
  1245.                     }
  1246.                 }
  1247.                 else
  1248.                 {
  1249.                     if (unlink(buffer1))
  1250.                     {
  1251.                         message(6,"!Can not delete %s.",buffer1);
  1252.                         exit(2);
  1253.                     }
  1254.                 }
  1255.                 return 1;
  1256.             }
  1257.             else
  1258.             {
  1259. #ifdef LINN
  1260.                 message(6,"!Fatal: Archiver error %d", net);
  1261.                 sprint(buffer1,"%s%s",mailpath,found);
  1262.                 sprint(buffer2, "%s%11.11s%c", mailpath, found,
  1263.                      found[11] + 'A' - '0');
  1264.                 message(6,"!Packet renamed to %11.11s%c", found,
  1265.                      *(found+11) + 'A' - '0');
  1266.                 if (rename(buffer1,buffer2))
  1267.                 {
  1268.                     message(6,"!Can not rename %s to %s",buffer1,
  1269.                             buffer2);
  1270.                     exit(2);
  1271.                 }
  1272. #else
  1273.                 message(6,"!Fatal: ARChiver error");
  1274. #endif
  1275.                 return 0; /* Archiver went wrong, abort else end-less loop */
  1276.             }
  1277.         }
  1278.         found=fnext();
  1279.     }
  1280.     while (found);
  1281.     return 0;
  1282. }
  1283.  
  1284. void mv_pkt()                           /* rename packet .pkt -> .bkt */
  1285. {
  1286.         char tmppkt[80];
  1287.  
  1288.         if (pkt!=NULL)
  1289.         {
  1290.                 fclose(pkt);
  1291.                 pkt=NULL;
  1292.         }
  1293.         strcpy(tmppkt,packet);
  1294.         strcpy(&tmppkt[strlen(packet)-3],"BKT");
  1295.         if (rename(packet,tmppkt))
  1296.         {
  1297.                 message(6,"!Cannot rename %s to %s",packet,tmppkt);
  1298.                 exit(2);
  1299.         }
  1300.         else message(6,"!Bad packet (%s > %s)",packet,tmppkt);
  1301.         *packet= '\0';
  1302. }
  1303.  
  1304. int open_pack()                 /* open mailpacket */
  1305. {
  1306.     char *p;                /* workhorse.. */
  1307.     char *ffirst();         /* find file with name */
  1308.     char temp[80];          /* temp. storage */
  1309.  
  1310. #ifdef LINN
  1311.     char type[10];          /* string for packet type */
  1312. #endif
  1313.     
  1314.     if (ask)                /* should ask for packet-name? */
  1315.     {
  1316.         print("Packet name: ");
  1317.         scanf("%79s",packet);
  1318.         if (!*packet) return 0;
  1319.     }
  1320.     else
  1321.     {
  1322.         sprint( temp, "%s*.PKT", mailpath);
  1323.         p=ffirst(temp);                       /* get the first packet */
  1324.         if (!p || !*p) return 0;              /* no packet found */
  1325.         sprint( packet, "%s%s", mailpath, p);
  1326.         message(2,"+Import %s",packet);
  1327.     }
  1328.     if ((pkt=fopen(packet, BREAD))==NULL)
  1329.     {
  1330.         message(6,"-Fatal: Can't open packet.");
  1331.         exit(1);    /* sysop gave wrong name, or it's a system error.. */
  1332.     }
  1333.     if (fread((char *)&phdr, sizeof(struct _pkthdr), 1, pkt)!=1)
  1334.     {
  1335.         message(6,"-Empty or too small, not a packet!");
  1336.         mv_pkt();
  1337.         return open_pack();
  1338.     }
  1339.     if (phdr.ph_ver!=inteli(0x2))              /* check packet type */
  1340.     {
  1341.         message(6,"-Not a packet or wrong version");
  1342.         mv_pkt();
  1343.         return open_pack();
  1344.     }
  1345.     
  1346. #ifdef LINN /* Modification to accept incoming 4D packets */
  1347.     if(phdr.ph_rate==inteli(0x2))
  1348.     { /* fsc-0045, type 2.2 */
  1349.         fromzone= inteli(phdr.ph_ozone);
  1350.         fromnet= inteli(phdr.ph_onet);
  1351.         fromnode= inteli(phdr.ph_onode);
  1352.         frompoint= inteli(phdr.ph_dy);
  1353.         strcpy(type,"2.2");
  1354.     }
  1355.     else
  1356.     {
  1357.         int cw,cwcheck; /* cap word */
  1358.         
  1359.         cw=inteli(phdr.ph_rsvd[3]);
  1360.         cwcheck=inteli(phdr.ph_rsvd[1]);
  1361.         /* invert cw validation copy, byte order indep */
  1362.         cwcheck=((cwcheck << 8) & 0xFF00) | ((cwcheck >> 8) & 0x00FF);
  1363.         if((cw==cwcheck) && (cw & 0x0001))
  1364.         { /* fsc-0039 & fsc-0048 */
  1365.             fromzone= inteli(phdr.ph_ozone);
  1366.             fromnet= inteli(phdr.ph_onet);
  1367.             fromnode= inteli(phdr.ph_onode);
  1368.             frompoint= inteli(phdr.ph_rsvd[6]);
  1369.             /* fsc-0048 */
  1370.             if((fromnet==0xFFFF) && (frompoint!=0))
  1371.                 fromnet= inteli(phdr.ph_rsvd[0]);
  1372.             strcpy(type,"2+");
  1373.         }
  1374.         else
  1375.         { /* fsc-0001 */
  1376.             fromzone= inteli(phdr.ph_ozone);
  1377.             fromnet= inteli(phdr.ph_onet);
  1378.             fromnode= inteli(phdr.ph_onode);
  1379.             frompoint= 0;
  1380.             strcpy(type,"2");
  1381.         }
  1382.     }
  1383.     if (fromzone==0)
  1384.         fromzone=alias[0].zone;        /* default zone number to alias[0] rather than zone of latest packet */
  1385. #else
  1386.     fromzone= inteli(phdr.ph_ozone);
  1387.     fromnet= inteli(phdr.ph_onet);
  1388.     fromnode= inteli(phdr.ph_onode);
  1389.     frompoint= 0;
  1390. #endif
  1391.     
  1392.     get_passw(fromzone, fromnet, fromnode, frompoint);
  1393.     if (secure>1 && strncmp(ourpwd,phdr.ph_pwd,6))
  1394.     {
  1395.         message(6,"-PASSWORD ERROR");
  1396.         mv_pkt();
  1397.         return open_pack();
  1398.     }
  1399.   
  1400. #ifdef LINN
  1401.     message(2,"+Packet type %s from %u:%u/%u.%u",type,
  1402.                 fromzone,fromnet,fromnode,frompoint);
  1403. #else
  1404.     message(2,"+Packet from %u:%u/%u",inteli(phdr.ph_ozone),
  1405.                 inteli(phdr.ph_onet), inteli(phdr.ph_onode));
  1406. #endif
  1407.  
  1408.     if (verbose) message(1,"+Assembled: %d-%d-%d  %d:%02d:%02d", inteli(phdr.ph_dy), inteli(phdr.ph_mo)+1,
  1409.            inteli(phdr.ph_yr), inteli(phdr.ph_hr), inteli(phdr.ph_mn), inteli(phdr.ph_sc));
  1410.  
  1411. #ifndef LINN
  1412.     if (phdr.ph_rate && verbose) message(1,"+Baudrate: %d",inteli(phdr.ph_rate));
  1413. #endif
  1414.  
  1415.     return 1;
  1416. }
  1417.  
  1418. static int openarea;
  1419.  
  1420. void open_area(area)                         /* open a certain message-area */
  1421. int area;                               /* number of area to open */
  1422. {
  1423.     char name[80];                      /* areaname */
  1424.  
  1425.     openarea= area;
  1426.     if (area==mailarea)
  1427.     {
  1428.         msg= MMSG;
  1429.         hdr= MHDR;
  1430.         return;
  1431.     }
  1432.  
  1433.     sprint( name, "%s.MSG", AreaPath[area]);
  1434.     if ((msg=fopen(name, BRUP))==NULL) msg=fopen(name, BWUP);
  1435.     sprint( name, "%s.HDR", AreaPath[area]);
  1436.     if ((hdr=fopen(name, BRUP))==NULL) hdr=fopen(name, BWUP);
  1437.     if (!msg || !hdr)                   /* not open? */
  1438.     {
  1439.         message(6,"-Error opening file(s) for area: %s",AreaPath[area]);
  1440.         exit(1);
  1441.     }
  1442.     fseek(hdr,0l,2);                    /* to end of files */
  1443.     fseek(msg,0l,2);
  1444. }
  1445.  
  1446. void close_area()                            /* close message area */
  1447. {
  1448.     if (openarea==mailarea) return;
  1449.  
  1450.     fclose(hdr);
  1451.     fclose(msg);
  1452. }
  1453.  
  1454. int read_hdr()                          /* read header of next message */
  1455. {
  1456.     char i,j;                           /* temp. storage */
  1457.     
  1458.     while (1)
  1459.     {
  1460.         i=getc(pkt);                    /* get the first 2 byte of new msg */
  1461.         j=getc(pkt);
  1462.  
  1463.         if (i==j)
  1464.         {
  1465.             /* this should be the end, but some utils **** up, so better
  1466.              * check it!
  1467.              */
  1468.             i = getc(pkt);
  1469.             if (feof(pkt) || i == 0x1a) return 0;    /* end of package */
  1470.  
  1471.             /* somehow there's still some data left. Process it! */
  1472.             ungetc(i,pkt);
  1473.             continue;
  1474.         }
  1475.  
  1476.         if (i!=2 || j!=0)               /* check message type */
  1477.         {
  1478.             /* there we go again, a bad message in this packet, let's resync! */
  1479.             message(1,"-garbage in '%s' at position %ld",packet,ftell(pkt));
  1480.  
  1481.             /* resync: */
  1482.             while (!feof(pkt))
  1483.             {
  1484.                 if ((i=getc(pkt))== 0x02)
  1485.                 {
  1486.                     /* found possible start of message! Test next byte */
  1487.                     if ((j=getc(pkt)) == 0x00) goto doit;
  1488.                     else ungetc(j,pkt);
  1489.                 }
  1490.             }
  1491.  
  1492.             /* save packet for closer examination by hand */
  1493.             mv_pkt();
  1494.             return 0;
  1495.         }
  1496.  
  1497. doit:
  1498.         if (fread(((char *)&mhdr)+2, (sizeof(struct _pktmsgs) -2), 1, pkt)!=1)
  1499.         {                                /* read error? */
  1500.             message(6,"-Unexpected end of package!");
  1501.             return 0;
  1502.         }
  1503.         return 1;                       /* all ok */
  1504.     }
  1505. }
  1506.  
  1507. void conv_hdr()
  1508. {
  1509.     char temp[200];                     /* temp. buffer */
  1510.     char *p;                            /* pointer in buffer */
  1511.     char ch;                            /* character from packet */
  1512.     long time();                        /* current time */
  1513.  
  1514.     /* Date routine modified once again. It's still giving LOTS of trouble.. */
  1515.     /* Drop me a message if you've found a bomb free way to read it!         */
  1516.     ch = -1;
  1517.     for (p=temp; p<temp+20 && !feof(pkt) && ch;)
  1518.     {
  1519.         ch=getc(pkt);
  1520.         *p++=ch;
  1521.     }
  1522.  
  1523.     while (p++ < temp+20 && (ch=getc(pkt))=='\0') ;
  1524.     if (ch) ungetc(ch,pkt);
  1525.  
  1526.     strncpy(hhdr.time,temp,20);
  1527.     hhdr.time[19]='\0';
  1528.  
  1529.     ch=-1;
  1530.     for(p=temp; ch && p<temp+200 && !feof(pkt);)           /* to */
  1531.     {
  1532.         ch=getc(pkt);
  1533.         *p++=ch;
  1534.     }
  1535.     strncpy(hhdr.to,temp,36);
  1536.     hhdr.to[35]='\0';
  1537.     ch=-1;
  1538.     for(p=temp; ch && p<temp+200 && !feof(pkt);)     /* from */
  1539.     {
  1540.         ch=getc(pkt);
  1541.         *p++=ch;
  1542.     }
  1543.     strncpy(hhdr.from,temp,36);
  1544.     hhdr.from[35]='\0';
  1545.     ch=-1;
  1546.     for(p=temp; ch && p<temp+200 && !feof(pkt);)     /* topic */
  1547.     {
  1548.         ch=getc(pkt);
  1549.         *p++=ch;
  1550.     }
  1551.     strncpy(hhdr.topic,temp,72);
  1552.     hhdr.topic[71]='\0';
  1553.     hhdr.create=time(NULL);             /* created at receive date */
  1554.     hhdr.up=hhdr.parent=0;              /* no connection to other messages */
  1555.     hhdr.flags=inteli(mhdr.pm_attr) & ~(KILLSEND|MSGLOCAL|MSGFWD|SENT|ORPHAN|DELETED);
  1556.     hhdr.cost=inteli(mhdr.pm_cost);
  1557.     hhdr.reads=0;
  1558.     hhdr.Ozone=hhdr.Dzone= (fromzone != 0) ? fromzone : ourzone;
  1559.     hhdr.Dpoint=hhdr.Opoint=0;          /* not known yet */
  1560.     hhdr.Onet=inteli(mhdr.pm_onet);
  1561.     hhdr.Onode=inteli(mhdr.pm_onode);
  1562.     hhdr.Dnet=inteli(mhdr.pm_dnet);
  1563.     hhdr.Dnode=inteli(mhdr.pm_dnode);
  1564.     for (ch=0; ch<8; ch++) hhdr.mailer[ch]=0;
  1565.     for (ch=0; ch<nalias; ch++)
  1566.     {   /* It's one of our points? (Onet ok && pkthdr ok??) */
  1567.         if (hhdr.Onet==alias[ch].pointnet && alias[ch].point==0 &&
  1568.             inteli(phdr.ph_onet)==alias[ch].pointnet)
  1569.         {
  1570.             /* Gee, one of our points! */
  1571.             hhdr.Onet=alias[ch].net;
  1572.             hhdr.Opoint=hhdr.Onode;
  1573.             hhdr.Onode=alias[ch].node;
  1574.  
  1575.             /* And get out of the loop */
  1576.             break;
  1577.         }
  1578.     }
  1579. }
  1580.  
  1581. int ourmessage()                        /* message for this node? */
  1582. {
  1583.     int i;                              /* silly counter */
  1584.     
  1585.     for (i=0;i<nalias;i++)
  1586.     {
  1587.        if (alias[i].point && alias[i].pointnet==hhdr.Dnet &&
  1588.            alias[i].point==hhdr.Dnode && alias[i].zone==hhdr.Dzone) return 1;
  1589.        if (hhdr.Dzone==alias[i].zone && alias[i].net==hhdr.Dnet &&
  1590.            alias[i].node==hhdr.Dnode && alias[i].point==hhdr.Dpoint) return 1;
  1591. #ifdef LINN
  1592.        /* if we are a point and the message is from_AND_to our boss, then
  1593.           we consider it as to us - needed for importing echomain on points
  1594.           with a tosscan boss - ugly ... - vp */
  1595.        if (hhdr.Dzone==hhdr.Ozone && hhdr.Ozone==alias[i].zone && alias[i].net==hhdr.Dnet &&
  1596.        hhdr.Dnet==hhdr.Onet && hhdr.Dnode==hhdr.Onode && hhdr.Dpoint==hhdr.Opoint &&
  1597.            alias[i].node==hhdr.Dnode && alias[i].point && hhdr.Dpoint==0) return 1;
  1598. #endif
  1599.     }
  1600.     return 0;
  1601. }
  1602.  
  1603. int read_line()
  1604. {
  1605.     int ch;
  1606.   
  1607.     ch=getc(pkt);
  1608.     while (!feof(pkt) && ch && ch!=2 && ms<MESSAGE+(30*1024-10))
  1609.     {
  1610.         switch(ch)
  1611.         {
  1612.           case '\r': *ms++='\n';
  1613.                      *ms='\0';
  1614.                      return 0;
  1615.           case '\n':
  1616.           case 0x7f:
  1617.           case 0x8d:
  1618.           case 0x8a: 
  1619.                      if (verbose > 3) print("`%02x`",ch);
  1620.                      break;
  1621.           default:   *ms++=ch;
  1622.                      if (verbose > 3) print("%c",ch);
  1623.         }
  1624.         ch=getc(pkt);
  1625.     }
  1626.  
  1627.     *ms++='\n';
  1628.     *ms++=0;
  1629.     if (feof(pkt) && ch)
  1630.     {
  1631.         message(6,"-Unexpected end of package!");
  1632.         return -2;
  1633.     }
  1634.  
  1635.     if (ch==2)
  1636.     {
  1637.         message(6,"-Cripled message");
  1638.         fseek(pkt,-1L,1);
  1639.     }
  1640.  
  1641.     if (ms>=MESSAGE+((30*1024)-10))
  1642.     {
  1643.         message(2,"-Message too long, will not be echoed anymore");
  1644.         while (!feof(pkt) && ch) ch=getc(pkt);   /* too long, skip rest! */
  1645.         hhdr.flags |= SENT;                      /* signal it being sent */
  1646.     }
  1647.     return -1;
  1648. }
  1649.  
  1650. void Iadress(str, zone, net, node)
  1651. char *str;
  1652. short *zone, *net, *node;
  1653. {
  1654.     char *p;
  1655.     int zo, ne, no;
  1656.    
  1657.     for (p=str; *p && isspace(*p); p++) ;
  1658.     if (sscanf(p, "%d:%d/%d", &zo, &ne, &no)!=3)
  1659.     {
  1660.         message(6,"!INTL error in %s.", str);
  1661.         *zone=0;
  1662.         return;
  1663.     }
  1664.     *zone= zo; *node= no; *net= ne;
  1665. }
  1666.  
  1667. #define NORMAL  1
  1668. #define SKIP    4
  1669.  
  1670. int line_type(line)
  1671. char *line;
  1672. {
  1673.     char *p, *q;
  1674.     int j;
  1675.    
  1676.     if (*line!=0x01) return NORMAL;
  1677.  
  1678.     if (verbose > 3) print("^A line: %s\n",line+1);
  1679.     
  1680.     /* Parse and remove INTL, FMPT and TOPT */
  1681.     if (!strnicmp(line+1,"INTL",4))
  1682.     {
  1683.         /* We've got an international (interzone) adress so parse it */
  1684. #ifdef LINN
  1685.         Iadress(line+5,(short *)&hhdr.Dzone,(short *) &hhdr.Dnet,(short *) &hhdr.Dnode);
  1686. #else
  1687.         Iadress(line+5,(int *)&hhdr.Dzone,(int *) &hhdr.Dnet,(int *) &hhdr.Dnode);
  1688. #endif
  1689.         p=line+8;
  1690.         while (*p && !isspace(*p)) ++p;
  1691. #ifdef LINN
  1692.         Iadress(p,(short *) &hhdr.Ozone,(short *) &hhdr.Onet,(short *) &hhdr.Onode);
  1693. #else
  1694.         Iadress(p,(int *) &hhdr.Ozone,(int *) &hhdr.Onet,(int *) &hhdr.Onode);
  1695. #endif
  1696.         return SKIP;
  1697.     }
  1698.  
  1699.     if (!strnicmp(line+1,"FMPT",4))
  1700.     {
  1701.         if (hhdr.Opoint) return NORMAL;
  1702.         for(p=line+5;*p && isspace(*p);++p) ;
  1703.         q = p;
  1704.         j = 0;
  1705.         while (isdigit(*p))
  1706.         {
  1707.             j *= 10;
  1708.             j += *p-'0';
  1709.             ++p;
  1710.         }
  1711.         if (j==0)
  1712.         {
  1713.             message(6,"!FMPT error in %s",line+1);
  1714.             return NORMAL;
  1715.         }
  1716.         hhdr.Opoint=j;
  1717.         if (*p=='.')        /* more point numbers?? */
  1718.         {
  1719.             while (*p) *q++=*p++;
  1720.             return NORMAL;
  1721.         }
  1722.         return SKIP;
  1723.     }
  1724.     if (!strnicmp(line+1,"TOPT",4))
  1725.     {
  1726.         if (verbose > 3) print("TOPT line %s\n",line+1);
  1727.  
  1728.         for(p=line+5;*p && isspace(*p);++p) ;
  1729.         q = p;
  1730.         j = 0;
  1731.         while (isdigit(*p))
  1732.         {
  1733.             j *= 10;
  1734.             j += *p-'0';
  1735.             ++p;
  1736.         }
  1737.         if (j==0)
  1738.         {
  1739.             message(6,"!TOPT error in %s",line+1);
  1740.             return NORMAL;
  1741.         }
  1742.         hhdr.Dpoint=j;
  1743.         if (*p=='.')        /* more point numbers?? */
  1744.         {
  1745.             while (*p) *q++=*p++;
  1746.             return NORMAL;
  1747.         }
  1748.         return SKIP;
  1749.     }
  1750.  
  1751.     /* Leave everything we don't know about at the same place in the message */
  1752.     return NORMAL;
  1753. }
  1754.  
  1755. char *next_str (p, lookfor)
  1756. char *p;
  1757. char *lookfor;
  1758. {
  1759.    extern char *strchr();
  1760.    char *found;
  1761.  
  1762.     if (verbose > 4) print ("Look for '%s'\n", lookfor);
  1763.  
  1764.     found=p;
  1765.     while (1)
  1766.     {
  1767.         found = strchr(found, *lookfor);
  1768.  
  1769.       /* Found anything at all? */
  1770.         if (found == NULL)
  1771.         {
  1772.             if (verbose > 4) print("End-Of-Message\n");
  1773.             return NULL;
  1774.         }
  1775.  
  1776.         if (verbose > 4) print ("Match first char in '%20.20s'\n", found);
  1777.  
  1778.         if (strncmp (found, lookfor, strlen(lookfor)))
  1779.         {
  1780.             ++found;
  1781.             if (verbose > 4) print("match FAIL\n");
  1782.             continue;
  1783.         }
  1784.         else
  1785.         {
  1786.             if (verbose > 4) print("match OK\n");
  1787.             return found;
  1788.         }
  1789.     }
  1790. }
  1791.  
  1792. char *GetArea()
  1793. {
  1794.         char *p;
  1795.  
  1796.         /* Check for AREA line at start of message */
  1797.         if (!strncmp(MESSAGE,"AREA:",5)) return MESSAGE;
  1798.         if (!strncmp(MESSAGE,"\01AREA:",6)) return MESSAGE;
  1799.  
  1800.         /* Not at start of message, somewhere else in the message? */
  1801.         if ( (p=next_str(MESSAGE,"\n\01AREA:"))!=NULL ||
  1802.              (p=next_str(MESSAGE,"\nAREA:"))!=NULL ) return p;
  1803.  
  1804.         /* No AREA line found in message */
  1805.         return NULL;
  1806. }
  1807.              
  1808. int read_msg()
  1809. {
  1810.     char ch;
  1811.     int result;
  1812.     char temp[80];                  /* temp. storage */
  1813.     char *p,*q;                     /* pointer in MESSAGE buffer */
  1814.     
  1815.     ms=MESSAGE;                     /* initiatial state for new message */
  1816.    
  1817.     if (verbose > 3) print("Message body:\n");
  1818.  
  1819.     /* Now we're gonna read the entire message */
  1820.     do
  1821.     {
  1822.         p=ms;
  1823.         result= read_line();
  1824.         switch (line_type(p))
  1825.         {
  1826.             case NORMAL:
  1827.                          break;
  1828.             case SKIP  : ms=p;
  1829.         }
  1830.     }
  1831.     while (!result) ;
  1832.     
  1833.     /* we've got it! is it ECHOmail to us? */
  1834.     
  1835.     area=mailarea;
  1836.     *ms='\0';
  1837.  
  1838.     /* Make sure endbody points to the trailing zero */
  1839.     endbody= ms;
  1840.     while (*endbody=='\0' && endbody>MESSAGE) endbody--;
  1841.     endbody++;
  1842.  
  1843.     if (verbose > 2) print("It is %sto us.\n",ourmessage() ? "" : "not ");
  1844.  
  1845.     if ( (p=GetArea())!=NULL )
  1846.     {                                 /* Gee, an echomail message! */
  1847.         hhdr.Dpoint = 0;              /* Clear point fields        */
  1848.         hhdr.Opoint = 0;
  1849.         if (ourmessage())             /* only toss our messages */
  1850.         {
  1851.             q= p;
  1852.             while (!(isspace(*p) || *p==':')) ++p; /* skip to 'spaces' */
  1853.             while ((isspace(*p) || *p==':')) ++p;  /* skip 'spaces' */
  1854.             ch=0;
  1855.             while (*p && !isspace(*p))
  1856.             {
  1857.                 temp[ch++]=*p++;
  1858.             }
  1859.             temp[ch]=0;
  1860.  
  1861.             if (verbose > 2) print("Its echomail, the area is >%s<\n",temp);
  1862.  
  1863.             for (area=0; area<msgareas; area++)
  1864.             {
  1865.                 if (!strcmp(temp,AreaName[area]))
  1866.                 {
  1867.                     int i;
  1868.  
  1869.                     /* secure mode? */
  1870.                     if (!secure) goto gotit;
  1871.  
  1872.                     /* Yep, check feed for valid address */
  1873.                     if (ToZone[area]==NULL) continue;
  1874.                     for (i=1; ToZone[area][i]||ToNet[area][i]; i++)
  1875.                     {
  1876.                         if (hhdr.Ozone==ToZone[area][i] &&
  1877.                             hhdr.Onet==ToNet[area][i] &&
  1878.                             hhdr.Onode==ToNode[area][i]) goto gotit;
  1879.                     }
  1880.                 }
  1881.             }
  1882.  
  1883.             if (area>=msgareas)          /* unknown? */
  1884.             {
  1885.                 area=badarea;
  1886.             }
  1887.             else
  1888.             {
  1889. gotit:
  1890.                 while (*p=='\n') p++;
  1891.  
  1892.                 memmove(q,p,strlen(p)+1);  /* get rid of useless line */
  1893.                                 /*    ^ Don't forget trailing zero!! */
  1894.                 endbody = endbody - (p-q);
  1895.  
  1896.                 sprintf(ThisArea,"%sAREA:%s\n", use_kludge ? "\01":"",
  1897.                         AreaName[area]);
  1898.             }
  1899.         }
  1900.     }
  1901.  
  1902.     mend= endbody;
  1903.  
  1904.     return (result==-1);                    /* if result<>-1 serious trouble */
  1905. }
  1906.  
  1907. void GetThem(msg, str, szones, snets, snodes, spoints, tseen)
  1908. char *msg;
  1909. char *str;
  1910. unsigned szones[];
  1911. unsigned snets[];
  1912. unsigned snodes[];
  1913. unsigned spoints[];
  1914. int *tseen;
  1915. {
  1916.     unsigned j, last_net;
  1917.     char *p,*q,*r;
  1918. #ifdef LINN
  1919.     int i;
  1920. #endif
  1921.  
  1922.     last_net = 65535U;
  1923.     r=msg;
  1924.  
  1925.     while ((p=next_str(r,str))!=NULL)
  1926.     {
  1927.         q=p;
  1928.        /* get begin of this line */
  1929.         while (q > MESSAGE && *q!='\n') --q;
  1930.         r=q;
  1931.         if (*p=='\n') ++p;
  1932.  
  1933.         while (*p && *p!='\n')        /* not the end of the line */
  1934.         {
  1935.            /* found a net/node pair? */
  1936.             if (isdigit(*p))
  1937.             {
  1938.                /* get the number. */
  1939.                 getint(&p, &j);
  1940.  
  1941.                /* Is it a net/node pair? */
  1942.                 if (*p == ':')
  1943.                 {
  1944. #ifdef LINN
  1945.         /* simply strip the zone number, because there are some
  1946.            problems parsing them and I'm not sure other parts of
  1947.            import would works ok if the parsing was correctly
  1948.            done. VP */
  1949.            p++;
  1950.            getint (&p, &j);
  1951.         }
  1952. #else
  1953.                     if (getaddress(p+1, &szones[*tseen], &snets[*tseen],
  1954.                                     &snodes[*tseen], &spoints[*tseen])!=6)
  1955.                     {
  1956.                         message(6,"!Illegal address %s",p);
  1957.                         *tseen--;       /* because it's incremented below */
  1958.                     }
  1959.                     while (*p && !isspace(*p)) p++;
  1960.                     szones[*tseen]=j;
  1961.                 }
  1962.                 else
  1963.                 {
  1964. #endif
  1965.                     szones[*tseen]=ourzone;
  1966.                     spoints[*tseen]=0;
  1967.                     
  1968.                     if (*p == '/')
  1969.                     {
  1970.                         ++p;
  1971.                         last_net = snets[*tseen] = j;
  1972.                         getint(&p, &snodes[*tseen]);
  1973.                     }
  1974.                     else
  1975.                     {
  1976.                         snets[*tseen] = last_net;
  1977.                         snodes[*tseen] = j;
  1978.                     }
  1979.                     if (last_net==ourpointnet)
  1980.                     {
  1981.                         spoints[*tseen]=snodes[*tseen];
  1982. #ifdef LINN /* pointnet/point -> net/node.point expansion
  1983.                 converts to primary address instead of 1st feed alias's
  1984.                 pointnet */
  1985.                         for (i=0; i < nalias; i++)
  1986.                         {
  1987.                             if (alias[i].pointnet==ourpointnet)
  1988.                             {
  1989.                                 snets[*tseen]=alias[i].net;
  1990.                                 snodes[*tseen]=alias[i].node;
  1991.                                 break;
  1992.                             }
  1993.                         }
  1994. #else
  1995.                         snets[*tseen]=ournet;
  1996.                         snodes[*tseen]=ournode;
  1997. #endif
  1998.                     }
  1999. #ifndef LINN
  2000.                 }
  2001. #endif
  2002.  
  2003.                 if (verbose > 4) print ("Got %d:%d/%d.%d\n", szones[*tseen],snets[*tseen],
  2004.                         snodes[*tseen],spoints[*tseen]);
  2005.  
  2006.                 if (*tseen<940)
  2007.                 {
  2008.                     ++*tseen;
  2009.                 }
  2010.             }
  2011.             else
  2012.             {
  2013.                 ++p;
  2014.             }
  2015.         }   /* end while for this line */
  2016.         while (*p)
  2017.         {
  2018.             *q++=*p++;          /* copy rest of the message to delete line */
  2019.         }
  2020.         *q=0;
  2021.         mend=q;
  2022.     } /* end while for lines.. */
  2023. }
  2024.  
  2025. /* I've seen better sort algoritmes, so do you undoubtely, but this one works
  2026.  * alright and for these small numbers it doesn't matter.
  2027.  * (Routine taken from a nice book on algorithems by L. Ammeraal as far
  2028.  *  as I recall, it's a long time ago I even looked at this code...)
  2029.  */
  2030.  
  2031. void SortThem(zones,nets,nodes,points,nr,chpoints)
  2032. unsigned zones[], nets[], nodes[], points[];
  2033. int *nr, chpoints;
  2034. {
  2035.     register int i, i1, left=0, right=(*nr)-1, temp=0;
  2036.     unsigned ne1,ne2,no1,no2,p1,p2;
  2037.  
  2038.     if (verbose > 5) print("start sorting now....\n");
  2039.  
  2040.    /* sort them all (not recursive sort to prevent stack problems) */
  2041.     do
  2042.     {
  2043.         for (i=left; i<right; i++)
  2044.         {
  2045.             i1=i+1;
  2046.             if (chpoints && points[i])
  2047.             {
  2048.                 ne1=ourpointnet;
  2049.                 no1=points[i];
  2050.                 p1=0;
  2051.             }
  2052.             else
  2053.             {
  2054.                 ne1=nets[i];
  2055.                 no1=nodes[i];
  2056.                 p1=points[i];
  2057.             }
  2058.             if (chpoints && points[i1])
  2059.             {
  2060.                 ne2=ourpointnet;
  2061.                 no2=points[i1];
  2062.                 p2=0;
  2063.             }
  2064.             else
  2065.             {
  2066.                 ne2=nets[i1];
  2067.                 no2=nodes[i1];
  2068.                 p2=points[i1];
  2069.             }
  2070.             if ((zones[i] > zones[i1]) || ((zones[i] == zones[i1]) &&
  2071.                 ((ne1 > ne2) || ((ne1==ne2) && 
  2072.                 ((no1>no2) || ((no1==no2) && (p1>p2) ))))))
  2073.             {
  2074.                 temp=zones[i]; zones[i]=zones[i1]; zones[i1]=temp;
  2075.                 temp=nets[i]; nets[i]=nets[i1]; nets[i1]=temp;
  2076.                 temp=nodes[i]; nodes[i]=nodes[i1]; nodes[i1]=temp;
  2077.                 temp=points[i]; points[i]=points[i1]; points[i1]= temp;
  2078.                 temp=i;
  2079.             }
  2080.         }
  2081.         right=temp;
  2082.  
  2083.         /* Still with me? No?!? I'm not sure I do understand it myself
  2084.          * anymore (and the original routine was so simple).
  2085.          */
  2086.  
  2087.         for(i=right; i>left; i--)
  2088.         {
  2089.             i1=i-1;
  2090.             if (chpoints && points[i])
  2091.             {
  2092.                 ne1=ourpointnet;
  2093.                 no1=points[i];
  2094.                 p1=0;
  2095.             }
  2096.             else
  2097.             {
  2098.                 ne1=nets[i];
  2099.                 no1=nodes[i];
  2100.                 p1=points[i];
  2101.             }
  2102.             if (chpoints && points[i1])
  2103.             {
  2104.                 ne2=ourpointnet;
  2105.                 no2=points[i1];
  2106.                 p2=0;
  2107.             }
  2108.             else
  2109.             {
  2110.                 ne2=nets[i1];
  2111.                 no2=nodes[i1];
  2112.                 p2=points[i1];
  2113.             }
  2114.             if ((zones[i1] > zones[i]) || ((zones[i1] == zones[i]) &&
  2115.                 ((ne2 > ne1) || ((ne2==ne1) && 
  2116.                 ((no2>no1) || ((no2==no1) && (p2>p1) ))))))
  2117.             {
  2118.                 temp=zones[i]; zones[i]=zones[i1]; zones[i1]=temp;
  2119.                 temp=nets[i]; nets[i]=nets[i1]; nets[i1]=temp;
  2120.                 temp=nodes[i]; nodes[i]=nodes[i1]; nodes[i1]=temp;
  2121.                 temp=points[i]; points[i]=points[i1]; points[i1]= temp;
  2122.                 temp=i;
  2123.             }
  2124.         }
  2125.         left=temp;
  2126.  
  2127.         if (verbose > 5) print("Left: %d        Right: %d\n",left,right);
  2128.  
  2129.     }
  2130.     while (left<right);
  2131.  
  2132.     if (verbose > 5) print("Sorted.\n");
  2133.  
  2134.    /* get rid of duplicates now */
  2135.     temp=*nr;
  2136.     for(i1=i=1; i<temp; i++)
  2137.     {
  2138.         if (zones[i]!=zones[i-1] || nets[i]!=nets[i-1] ||
  2139.             nodes[i]!=nodes[i-1] || points[i]!=points[i-1])
  2140.         {
  2141.             zones[i1]=zones[i];
  2142.             nets[i1]=nets[i];
  2143.             nodes[i1]=nodes[i];
  2144.             points[i1++]=points[i];
  2145.         }
  2146.     }
  2147.     if (i!=1) *nr=i1;
  2148.  
  2149.     if (verbose > 5) print("Original: %d      Now: %d\n", i,i1);
  2150. }
  2151.  
  2152. /* CheckSeen checks your seen-bys to find any missing nodes you're
  2153.  * supposed to feed this echo to.
  2154.  */
  2155. void CheckSeen()
  2156. {
  2157.     int i, fo, found, k, what;
  2158.     
  2159.     fo= found= 0;
  2160.     i= 1;
  2161.  
  2162.     while (ToZone[area][i] || ToNet[area][i])
  2163.     {
  2164.         if (verbose > 2) print("Check for send to %u:%u/%u.%u\n",ToZone[area][i],ToNet[area][i],
  2165.         ToNode[area][i],ToPoint[area][i]);
  2166.  
  2167.         for (k=found; k < nSeen; k++)
  2168.         {
  2169.             if (SeenNet[k]==ToNet[area][i] && SeenNode[k]==ToNode[area][i] && 
  2170.                 SeenPoint[k]==ToPoint[area][i])
  2171.             {
  2172.                 SendTo[i]=0;
  2173.                 if (SeenZone[k]==ToZone[area][i]) found=k;
  2174.                 break;
  2175.             }
  2176.         }
  2177.         if (k==nSeen)
  2178.         {
  2179.             SendTo[i]=1;
  2180.             fo=1;
  2181.         }
  2182.         ++i;
  2183.     }
  2184.     if (!fo) return;
  2185.  
  2186.     if (verbose > 2) print("Should send message to:");
  2187.  
  2188.     i=0;
  2189.     while (++i, ToNet[area][i]||ToNode[area][i])
  2190.     {
  2191.         if (!SendTo[i]) continue;
  2192.  
  2193.         if (verbose > 2) print("%u:%u/%u.%u  ",ToZone[area][i],ToNet[area][i],
  2194.                 ToNode[area][i],ToPoint[area][i]);
  2195.  
  2196.         SeenZone[nSeen]=ToZone[area][i];
  2197.         SeenNet[nSeen]=ToNet[area][i];
  2198.         SeenNode[nSeen]=ToNode[area][i];
  2199.         SeenPoint[nSeen++]=ToPoint[area][i];
  2200.     }
  2201.  
  2202.     if (verbose > 2) print("\nSort now..");
  2203.  
  2204.     SortThem(SeenZone,SeenNet,SeenNode,SeenPoint,&nSeen,1);
  2205.  
  2206.     if (verbose > 2) print("\nCreating message to ");
  2207.  
  2208.     i=0;
  2209.     while (++i, ToNet[area][i]||ToNode[area][i])
  2210.     {
  2211.         if (!SendTo[i]) continue;
  2212.         if (verbose > 2)
  2213.                 print("%u:%u/%u.%u ",ToZone[area][i],ToNet[area][i],
  2214.                         ToNode[area][i],ToPoint[area][i]);
  2215.  
  2216.         what= ((ToPoint[area][i]) ? POINTS : 0) |
  2217.                (use_tiny ? LOCALS:OTHERS);
  2218.         writemessage(use_packet ? SCANFILE : OUTBOUND,what,
  2219.              ToZone[area][i],ToNet[area][i],ToNode[area][i],ToPoint[area][i]);
  2220.     }
  2221.  
  2222.     if (verbose > 2) print("\n");
  2223. }
  2224.  
  2225. void PurgeBlanks()           /* delete trailing blanks */
  2226. {
  2227.     char *p;
  2228.     
  2229.    /* point p at end of message */
  2230.     p=mend;
  2231.    /* if it's the trailing '\0' then skip it. */
  2232.     while (p>MESSAGE && *p==0) --p;
  2233.    /* back till begin of message or any non blank */
  2234.     while (p>MESSAGE && isspace(*p)) --p;
  2235.    /* p points to valid char now (non blank) so increment by one */
  2236.     *(++p)='\0';
  2237.     mend=p;
  2238. }
  2239.  
  2240. int CheckEcho()
  2241. {
  2242.     int i;
  2243.     
  2244.    /* first check if msg valid for sending. */
  2245.     if (hhdr.flags & SENT ||
  2246.         hhdr.flags & FILEATCH)  return 1;
  2247.  
  2248.     if (next_str(MESSAGE,"\nNOECHO") || next_str(MESSAGE,"\nnoecho")) return 1;
  2249.   
  2250.    /* Get the seen-bys (deletes the lines..) */
  2251.     nSeen=0;
  2252.     GetThem(MESSAGE, "\n\01SEEN-BY:", SeenZone, SeenNet, SeenNode,
  2253.             SeenPoint, &nSeen);
  2254.     GetThem(MESSAGE, "\nSEEN-BY:", SeenZone, SeenNet, SeenNode,
  2255.             SeenPoint, &nSeen);
  2256.  
  2257.     /* Check the number of seen-bys. If zero it's a bad message */
  2258.     if (nSeen == 0)
  2259.     {
  2260.         message(6,"-echomail missing seen-by lines --> badmsgs (%d)",
  2261. #ifdef LINN
  2262.                 nmsgs[badarea]+1);
  2263. #else
  2264.                 nmsgs[badarea]);
  2265. #endif
  2266.         hhdr.mailer[7] |= MSGSCANNED;
  2267.         area = badarea;
  2268.         return 1;
  2269.     }
  2270.  
  2271.     /* Add our primary address */
  2272.     SeenZone[nSeen]=ourzone;
  2273.     SeenNet[nSeen]=ournet;
  2274.     SeenNode[nSeen]=ournode;
  2275.     SeenPoint[nSeen++]=ourpoint;
  2276.  
  2277.    /* add our own numbers (AKAs etc.) */
  2278.     for (i=0;i<add_aka && i<nalias;i++)
  2279.     {
  2280. #ifdef LINN
  2281.         if (alias[i].zone==ourzone) {
  2282. #endif
  2283.             SeenZone[nSeen]=alias[i].zone;
  2284.             SeenNet[nSeen]=alias[i].net;
  2285.             SeenNode[nSeen]=alias[i].node;
  2286.             SeenPoint[nSeen++]=alias[i].point;
  2287. #ifdef LINN
  2288.     }
  2289. #endif
  2290.     }
  2291.  
  2292.    /* get them in the correct order again.. */
  2293.     SortThem(SeenZone,SeenNet,SeenNode,SeenPoint, &nSeen,0);
  2294.  
  2295.     if (verbose > 2)
  2296.     {
  2297.         print("Message SEEN-BY:");
  2298.         for (i=0;i<nSeen;i++) print(" %u:%u/%u.%u",SeenZone[i],SeenNet[i],
  2299.              SeenNode[i],SeenPoint[i]);
  2300.         print("\n");
  2301.     }
  2302.     
  2303.    /* get the path, not restored if not in use (get rid of line anyway..) */
  2304.     nPath=0;
  2305.     GetThem(MESSAGE, "\n\01PATH:", PathZone, PathNet, PathNode,
  2306.             PathPoint, &nPath);
  2307.  
  2308.     if (verbose > 2)
  2309.     {
  2310.         print("Message PATH:");
  2311.         for (i=0;i<nPath;i++) print(" %u:%u/%u.%u",PathZone[i],PathNet[i],
  2312.                 PathNode[i],PathPoint[i]);
  2313.         print("\n");
  2314.     }
  2315.     
  2316.    /* Get rid of all trailing blanks now. */
  2317.     PurgeBlanks();
  2318.  
  2319. #ifdef HELL_FREEZES_OVER
  2320.    /* Check if we've got an origin-line, it's a bad message if none found */
  2321.     if (next_str(MESSAGE,"\n * Origin:")==NULL)
  2322.     {
  2323.         message(6,"-echomail missing Origin line --> badmsgs");
  2324.         hhdr.mailer[7] |= MSGSCANNED;
  2325.         area = badarea;
  2326.         return 1;
  2327.     }
  2328. #endif
  2329.  
  2330.     endbody=mend;   /* message body ends HERE */
  2331.     
  2332.    /* Now check for nodes to send the message to (and send those msgs) */
  2333.     CheckSeen();
  2334.     
  2335.    /* Flag message as scanned */
  2336.     hhdr.mailer[7] |= MSGSCANNED;
  2337.     return 1;
  2338. }
  2339.  
  2340. void add(p) char *p;
  2341. {       while (*p)
  2342.         {       *mend++=*p++;
  2343.                 x++;
  2344.         }
  2345. }
  2346.  
  2347. void AddThem(addstr,zones,nets,nodes,points,nr,dopoints,dozones)
  2348. char *addstr;
  2349. unsigned zones[], nets[], nodes[], points[];
  2350. int nr, dopoints, dozones;
  2351. {
  2352.     unsigned lastnet, len, tnet, tnode;
  2353.     int i;
  2354.     char str[20];
  2355.     
  2356.     x=100;
  2357. #ifdef LINN
  2358.     lastnet=(unsigned) -1;
  2359. #else
  2360.     lastnet=-1;
  2361. #endif
  2362.     for(i=0; i<nr; i++)
  2363.     {
  2364.         if (zones[i]!=ourzone)
  2365.         {
  2366.             if (dozones)
  2367.             {
  2368. #ifdef LINN
  2369.                 tnet=(unsigned)-1;
  2370. #else
  2371.                 tnet=-1;
  2372. #endif
  2373.                 sprintf(str," %u:%u/%u.%u",zones[i],nets[i],nodes[i],points[i]);
  2374.             }
  2375.             else *str=0;
  2376.         }
  2377.         else
  2378.         {
  2379.             if (verbose > 3) print("%u/%u.%u -> ",nets[i],nodes[i],points[i]);
  2380.  
  2381.             if (points[i])
  2382.             {
  2383.                 tnet=ourpointnet;
  2384.                 tnode=points[i];
  2385.             }
  2386.             else
  2387.             {
  2388.                 tnet=nets[i];
  2389.                 tnode=nodes[i];
  2390.             }
  2391.             
  2392.             if (!dopoints && points[i] && !(points[i]==ourpoint &&
  2393.                 nodes[i]==ournode && nets[i]==ournet)) continue;
  2394.  
  2395.             if (lastnet==tnet) sprintf(str," %u",tnode);
  2396.             len=(int)strlen(str);
  2397.             if (lastnet!=tnet || (len+x > 76))
  2398.                 sprintf(str," %u/%u",tnet,tnode);
  2399.         }
  2400.         len=(int)strlen(str);
  2401.         if (len+x >76)
  2402.         {
  2403.             x=0;
  2404.             add(addstr);
  2405.         }
  2406.         if (verbose > 3) print("%s\n",str);
  2407.  
  2408.         add(str);
  2409.         lastnet=tnet;
  2410.     }
  2411.     *mend=0;
  2412. }
  2413.  
  2414. /* AddSeen adds seen-by lines to a message */
  2415. void AddSeen(what)
  2416. int what;
  2417. {
  2418.     char sline[20];
  2419.     int i;
  2420.  
  2421.     sprintf(sline, "\n%sSEEN-BY:", use_kludge ? "\01" : "");
  2422.     if (what&LOCALS)
  2423.     {
  2424.         for (i=1; ToNet[area][i]|ToNode[area][i]; ++i);
  2425.         AddThem(sline,&ToZone[area][1],&ToNet[area][1],
  2426.                 &ToNode[area][1],&ToPoint[area][1],i-1,
  2427.                (what&POINTS),(what&DIFFZONE));
  2428.     }
  2429.     else AddThem(sline,SeenZone,SeenNet,SeenNode,SeenPoint,
  2430.                   nSeen, (what&POINTS), (what&DIFFZONE));
  2431. }
  2432.  
  2433. void AddPath(add)
  2434. int add;
  2435. {
  2436.     int th=1;
  2437.     
  2438.     if (PathZone[nPath-1]==ourzone && PathNet[nPath-1]==ournet &&
  2439.         PathNode[nPath-1]==ournode && PathPoint[nPath-1]==ourpoint) --th;
  2440.     PathZone[nPath]=ourzone;
  2441.     PathNet[nPath]=ournet;
  2442.     PathNode[nPath]=ournode;
  2443.     PathPoint[nPath]=ourpoint;
  2444.     /* Only add all path nodes when in own zone */
  2445.     if (!add) AddThem("\n\01PATH:",PathZone,PathNet,PathNode,
  2446.                  PathPoint,nPath+th,-1,0);
  2447.     else AddThem("\n\01PATH:",&ourzone,&ournet,&ournode,&ourpoint,1,-1,0);
  2448. }
  2449.  
  2450. void OpenPacket(nr,zone,net,node,point)
  2451. int nr;
  2452. unsigned zone, net, node, point;
  2453. {
  2454.     struct time t;
  2455.     struct date d;
  2456.     struct _pkthdr phdr;
  2457.     char fname[80];
  2458.     int  i;
  2459.     int tzone, tnet, tnode, tpoint;
  2460.     
  2461.     tzone= ourzone;
  2462.     tnet= ournet;
  2463.     tnode= ournode;
  2464.     tpoint= ourpoint;
  2465.  
  2466.     if (verbose > 1) print("Open packet %u:%u/%u.%u\n",zone,net,node,point);
  2467.  
  2468.     /* Get password first before all information is destroyed */
  2469.     get_passw(zone,net,node,point);
  2470.     getalias(zone,net,node,point);
  2471.  
  2472.     /* save the 4-D address first */
  2473.     pktzone[nr]= zone;
  2474.     pktnet[nr]= net;
  2475.     pktnode[nr]= node;
  2476.     pktpoint[nr]= point;
  2477.  
  2478.     if (point)
  2479.     {
  2480.         for (i=0; i<nalias; i++)
  2481.         {
  2482.             if (alias[i].zone==zone && alias[i].net==net &&
  2483.                 alias[i].node==node && alias[i].point==0)
  2484.             {
  2485.                 net= alias[i].pointnet;
  2486.                 node= point;
  2487.                 point= 0;
  2488.                 pktfake[nr] = net;
  2489.                 break;
  2490.             }
  2491.         }
  2492.         if (point)
  2493.         {
  2494.             message(6,"!Can't scan for points of other BBSes!");
  2495.             exit(2);
  2496.         }
  2497.     }
  2498.     else
  2499.     {
  2500.         pktfake[nr] = 0;
  2501.     }
  2502.  
  2503.     /* try to open existing files, first .WM then .NM */
  2504.  
  2505. #ifdef LINN
  2506.     if (binkley) {
  2507.        if (zone==alias[0].zone) {
  2508.          sprint(fname, "%s%03z%03z00.HPT", hold, net, node);
  2509.          pktfile[nr]=fopen(fname, BRUP);
  2510.          if (pktfile[nr] == NULL) {
  2511.         sprint(fname, "%s%03z%03z00.OPT", hold, net, node);
  2512.             pktfile[nr]= fopen(fname,BRUP);
  2513.          }
  2514.        } else {
  2515.          sprint(fname, "%s.%03x%c%03z%03z00.HPT", holdbink, zone, DIRSEP, net, node);
  2516.          pktfile[nr]=fopen(fname, BRUP);
  2517.          if (pktfile[nr] == NULL) {
  2518.         sprint(fname, "%s.%03x%c%03z%03z00.OPT", holdbink, zone, DIRSEP, net, node);
  2519.             pktfile[nr]= fopen(fname,BRUP);
  2520.          }
  2521.        }
  2522.     } else {
  2523.        sprint(fname, "%s%02z%03z%03z.WM", hold, zone, net, node);
  2524.        pktfile[nr]= fopen(fname,BRUP);
  2525.        if (pktfile[nr] == NULL) {
  2526.         sprint(fname, "%s%02z%03z%03z.NM", hold, zone, net, node);
  2527.             pktfile[nr]= fopen(fname,BRUP);
  2528.        }
  2529.     }
  2530. #else
  2531.     sprint(fname, "%s%02z%03z%03z.WM", hold, zone, net, node);
  2532.     pktfile[nr]= fopen(fname,BRUP);
  2533.     if (pktfile[nr] == NULL) {
  2534.         sprint(fname, "%s%02z%03z%03z.NM", hold, zone, net, node);
  2535.         pktfile[nr]= fopen(fname,BRUP);
  2536.     }
  2537.  
  2538. #endif
  2539.  
  2540.     if (pktfile[nr]!=NULL)
  2541.     {
  2542.         fseek(pktfile[nr],-2L,2);
  2543.         ourzone= tzone;
  2544.         ournet= tnet;
  2545.         ournode= tnode;
  2546.         ourpoint= tpoint;
  2547.         return;
  2548.     }
  2549.  
  2550.     pktfile[nr]= fopen(fname,BWUP);
  2551.     if (pktfile[nr]==NULL)
  2552.     {
  2553.         message(6,"!Can't open file %s",fname);
  2554.         exit(1);
  2555.     }
  2556.  
  2557.     /* new packet, we've to make a header first */
  2558.     getdate((struct date *)&d);
  2559.     gettime((struct time *)&t);
  2560.     memset(&phdr, 0, sizeof(struct _pkthdr));
  2561.  
  2562.     /* are we a point and not to boss then re-address */
  2563.     if (ourpoint)
  2564.     {
  2565.         if (ournode!=node || ournet!=net || ourzone!=zone)
  2566.         {
  2567.             phdr.ph_onode= inteli(-1);
  2568.             phdr.ph_onet = inteli(ourpointnet);
  2569.         }
  2570.         else
  2571.         {
  2572.             phdr.ph_onode= inteli(ourpoint);
  2573.             phdr.ph_onet= inteli(ourpointnet);
  2574.         }
  2575.     }
  2576.     else
  2577.     {
  2578.         phdr.ph_onode=inteli(ournode);
  2579.         phdr.ph_onet=inteli(ournet);
  2580.     }
  2581.     phdr.ph_ozone=inteli(ourzone);
  2582.     phdr.ph_dnode=inteli(node);
  2583.     phdr.ph_dnet=inteli(net);
  2584.     phdr.ph_dzone=inteli(zone);
  2585.     phdr.ph_yr=inteli(d.da_year);
  2586.     phdr.ph_mo=inteli(d.da_mon-1);
  2587.     phdr.ph_dy=inteli(d.da_day-1);
  2588.     phdr.ph_hr=inteli(t.ti_hour);
  2589.     phdr.ph_mn=inteli(t.ti_min);
  2590.     phdr.ph_sc=inteli(t.ti_sec);
  2591.     phdr.ph_rate=0;
  2592.     phdr.ph_ver=inteli(2);
  2593.     phdr.ph_prod=inteli(isBERMUDA);
  2594.     strncpy(phdr.ph_pwd,ourpwd,8);
  2595.     if( fwrite((char *)&phdr, sizeof(struct _pkthdr), 1, pktfile[nr]) !=1)
  2596.     {
  2597.         message(6,"-Write error (disk full??)");
  2598.         exit(1);
  2599.     }
  2600.  
  2601.     ourzone= tzone;
  2602.     ournet= tnet;
  2603.     ournode= tnode;
  2604.     ourpoint= tpoint;
  2605. }
  2606.  
  2607. void ClosePacket(nr)
  2608. int nr;
  2609. {
  2610.     if (verbose > 1) print("Close packet\n");
  2611.  
  2612.     if (pktfile[nr])
  2613.     {
  2614.         pktzone[nr]= pktnet[nr]= pktnode[nr]= pktpoint[nr]= 0;
  2615.         if (fwrite("\0\0", 2, 1, pktfile[nr])!=1)
  2616.         {
  2617.             message(6,"!Error writing to package");
  2618.             exit(1);
  2619.         }
  2620.         fclose(pktfile[nr]);
  2621.         pktfile[nr]= NULL;
  2622.     }
  2623. }
  2624.  
  2625. void MakeHdr(nr,Mhdr)
  2626. int nr;
  2627. struct Hdr *Mhdr;
  2628. {
  2629.     struct _pktmsgs mh;
  2630.     
  2631.     if (verbose > 1) print("MakeHdr\n");
  2632.  
  2633.     mh.pm_ver=inteli(2);
  2634.     mh.pm_onode=inteli(Mhdr->Onode);
  2635.     mh.pm_onet=inteli(Mhdr->Onet);
  2636.     mh.pm_dnode=inteli(Mhdr->Dnode);
  2637.     mh.pm_dnet=inteli(Mhdr->Dnet);
  2638.     mh.pm_attr=inteli(Mhdr->flags&0x3413);
  2639.     mh.pm_cost=inteli(Mhdr->cost);
  2640.     fwrite((char *)&mh, sizeof(struct _pktmsgs), 1, pktfile[nr]);
  2641.     fprintf(pktfile[nr],"%19s",Mhdr->time);
  2642.     putc('\0',pktfile[nr]);
  2643.     fprintf(pktfile[nr],"%s",Mhdr->to);        /* from & to */
  2644.     putc('\0',pktfile[nr]);
  2645.     fprintf(pktfile[nr],"%s",Mhdr->from);
  2646.     putc('\0',pktfile[nr]);
  2647.     fprintf(pktfile[nr],"%s",Mhdr->topic);     /* topic */
  2648.     putc('\0',pktfile[nr]);
  2649.     
  2650. #ifdef LINN
  2651.     if (no_intl)
  2652. #endif
  2653.     if (Mhdr->Ozone && Mhdr->Dzone && (Mhdr->Ozone!=Mhdr->Dzone))
  2654.         fprintf(pktfile[nr],"\01INTL %d:%d/%d %d:%d/%d\r\n", Mhdr->Dzone,
  2655.           Mhdr->Dnet, Mhdr->Dnode, Mhdr->Ozone, Mhdr->Onet, Mhdr->Onode);
  2656. }
  2657.  
  2658. void PktWrite(nr, str, len)
  2659. int nr;
  2660. char *str;
  2661. int len;
  2662. {
  2663.     if (verbose > 1) print("PktWrite\n");
  2664.  
  2665.     while (len--)
  2666.     {
  2667.         if (*str=='\n') putc('\r',pktfile[nr]);
  2668.         else putc(*str,pktfile[nr]);
  2669.         str++;
  2670.         if (ferror(pktfile[nr]))
  2671.         {
  2672.                 exit(1);
  2673.         }
  2674.     }
  2675.     if (ferror(pktfile[nr]))
  2676.     {
  2677.         message(6,"!Error writing to packet-file");
  2678.         exit(1);
  2679.     }
  2680. }
  2681.  
  2682. void writemessage(where,what,zone,net,node,point)
  2683. int where;
  2684. int what;
  2685. unsigned zone,net,node,point;
  2686. {
  2687.     int i;
  2688.     static int j= -1;
  2689.     char sline[20];
  2690.     int empty= -1;
  2691.  
  2692.     memmove((char *) &Mhdr, (char *) &hhdr, sizeof(struct Hdr));
  2693. #ifdef LINN
  2694.     getalias (zone, net, node, point);
  2695. #endif
  2696.     mend=endbody;
  2697.     if (what)
  2698.     {
  2699.         if (zone!=ourzone) 
  2700.         {
  2701.             unsigned z[3],ne[3],no[3],p[3];
  2702.             int i;
  2703.             
  2704.             i=2;
  2705.             z[0]=ourzone; z[1]=ourzone;
  2706.             ne[0]=ournet; ne[1]=net;
  2707.             no[0]=ournode; no[1]=node;
  2708.             p[0]=ourpoint; p[1]=0;
  2709.             SortThem(z,ne,no,p,&i,1);
  2710.             sprintf(sline, "\n%sSEEN-BY:", use_kludge ? "\01" : "");
  2711.             AddThem(sline,z,ne,no,p,2,1,0);
  2712.         }
  2713.         else AddSeen(what);
  2714.         if (use_path) AddPath(zone!=ourzone);
  2715.  
  2716.         if (use_readdress)
  2717.         {
  2718.             Mhdr.Ozone = ourzone;
  2719.             Mhdr.Onet  = ournet;
  2720.             Mhdr.Onode = ournode;
  2721.             Mhdr.Opoint= ourpoint;
  2722.             if (ourpoint)
  2723.             {
  2724.                 Mhdr.Onet= ourpointnet;
  2725.                 Mhdr.Onode= ourpoint;
  2726.                 Mhdr.Opoint=0;
  2727.             }
  2728.         }
  2729.     }
  2730.     switch (where)
  2731.     {
  2732.       case OUTBOUND:
  2733.                     Mhdr.Mstart= ftell(MMSG);
  2734.                     echomsgs++;
  2735. #ifdef LINN
  2736.                     emsgs[area]++;
  2737. #endif
  2738.                     if (what)
  2739.                     {
  2740.                         if (fwrite(ThisArea, strlen(ThisArea),1, MMSG)!=1)
  2741.                         {
  2742.                             message(6,"!Fatal error writing to mail");
  2743.                             exit(1);
  2744.                         }
  2745.                         Mhdr.size=(int)strlen(ThisArea);
  2746.                     }
  2747.                     else Mhdr.size=0;
  2748.                     *mend++='\n';
  2749.                     *mend='\0';
  2750.                     Mhdr.size += (int)(mend-MESSAGE)+2;
  2751.                     Mhdr.Dzone = zone;
  2752.                     Mhdr.Dnet  = net;
  2753.                     Mhdr.Dnode = node;
  2754.                     Mhdr.Dpoint= point;
  2755.                     Mhdr.flags |= (MSGLOCAL|KILLSEND);
  2756.                     Mhdr.parent = 0;
  2757.                     for (i=0; i<8; i++) Mhdr.mailer[i]=0;
  2758.                     Mhdr.cost=0;
  2759.                     if (fwrite(MESSAGE, ((mend-MESSAGE)+2), 1, MMSG)!=1)
  2760.                     {
  2761.                         message(6,"!Fatal error writing to mail");
  2762.                         exit(1);
  2763.                     }
  2764.                     if (fwrite((char *) &Mhdr, sizeof(struct Hdr), 1, MHDR)!=1)
  2765.                     {
  2766.                         message(6,"!Fatal error writing to mail");
  2767.                         exit(1);
  2768.                     }
  2769.                     break;
  2770.       case SCANFILE:
  2771.                     echomsgs++;
  2772. #ifdef LINN
  2773.                     emsgs[area]++;
  2774. #endif
  2775.                     for (i=0; i<10; i++)
  2776.                     {
  2777.                         if (pktfile[i]==NULL) empty= i;
  2778.                         if (zone==pktzone[i] && net==pktnet[i] && 
  2779.                             node==pktnode[i] && point==pktpoint[i]) break;
  2780.                     }
  2781.  
  2782.                     if (i>=10)
  2783.                     {
  2784.                         if (empty != -1)
  2785.                         {
  2786.                             OpenPacket(empty,zone,net,node,point);
  2787.                             i= empty;
  2788.                         }
  2789.                         else
  2790.                         {
  2791.                             j= (j+1) < 10 ? j+1 : 1;
  2792.                             ClosePacket(j);
  2793.                             OpenPacket(j,zone,net,node,point);
  2794.                             i= j;
  2795.                         }
  2796.                     }
  2797.                     
  2798.                     *mend++='\n';
  2799.                     *mend='\0';
  2800.                     if (point) {
  2801.                         net = pktfake[i];
  2802.                         node = pktpoint[i];
  2803.                         point = 0;
  2804.                     }
  2805.                     Mhdr.Dzone = zone;
  2806.                     Mhdr.Dnet  = net;
  2807.                     Mhdr.Dnode = node;
  2808.                     Mhdr.Dpoint= point;
  2809.                     Mhdr.flags |= (MSGLOCAL);
  2810.                     Mhdr.cost=0;
  2811.                     MakeHdr(i,&Mhdr);
  2812.                     if (what)
  2813.                     {
  2814.                         PktWrite(i, ThisArea, (int)strlen(ThisArea));
  2815.                     }
  2816.                     PktWrite(i, MESSAGE, ((int)(mend-MESSAGE)+1));
  2817.                     break;
  2818.       case LOCAL:
  2819.       default:      message(6,"?Internal error %02x in messagewrite",where);
  2820.     }
  2821. }
  2822.  
  2823. /* Save message to local messagebase */
  2824. void savemessage(where,what)
  2825. int where;
  2826. int what;
  2827. {
  2828.     mend=endbody;
  2829. #ifdef LINN    /* do not save empty messages... usefull ??? */
  2830.     if (mend==MESSAGE)
  2831.         return;
  2832. #endif
  2833.  
  2834.     if (what)
  2835.     {
  2836.         AddSeen(what);
  2837.         if (use_path) AddPath(0);
  2838.     }
  2839.  
  2840. #ifdef LINN
  2841.     /* does not count messages to sysop in echomail */
  2842.     if ((!what && (!strnicmp(hhdr.to,"sysop",5))) || !strnicmp(hhdr.to,sysop,strlen(sysop)))
  2843. #else
  2844.     if (!strnicmp(hhdr.to,"sysop",5) || !strnicmp(hhdr.to,sysop,strlen(sysop)))
  2845. #endif
  2846.         smsgs[area]++;
  2847.  
  2848.     if (verbose)
  2849.     {
  2850.         clprint(": %s ",hhdr.from);
  2851.         if (area==mailarea)
  2852.            clprint("(%d:%d/%d.%d) ",hhdr.Ozone,hhdr.Onet,hhdr.Onode,hhdr.Opoint);
  2853.         clprint("> %s ", hhdr.to);
  2854.         if (area==mailarea)
  2855.            clprint("(%d:%d/%d.%d) ",hhdr.Dzone,hhdr.Dnet,hhdr.Dnode,hhdr.Dpoint);
  2856. #ifdef LINN
  2857.         clprint(", %s (msg %d)\n",AreaName[area],nmsgs[area]+1);
  2858. #else
  2859.         clprint(", %s (msg %d)\n",AreaName[area],nmsgs[area]);
  2860. #endif
  2861.     }
  2862.  
  2863.     nmsgs[area]++;
  2864.  
  2865. #ifdef LINN    /* passthrough area */
  2866.     if (!stricmp("PASSTHRU", AreaPath[area]))
  2867.         return;
  2868. #endif
  2869.  
  2870.     if (area!=lastarea)                     /* same area? */
  2871.     {
  2872.         if (lastarea!=-1) close_area();
  2873.         open_area(area);
  2874.         lastarea=area;
  2875.     }
  2876.  
  2877.     switch (where)
  2878.     {
  2879.       case LOCAL:   hhdr.Mstart= ftell(msg);
  2880.                     hhdr.size  = (int) (mend-MESSAGE)+1;
  2881.                     if (fwrite(MESSAGE, hhdr.size, 1, msg)!=1)
  2882.                     {
  2883.                         message(6,"!Fatal error writing message");
  2884.                         exit(1);
  2885.                     }
  2886.                     if (fwrite((char *) &hhdr, sizeof(struct Hdr), 1, hdr)!=1)
  2887.                     {
  2888.                         message(6,"!Fatal error writing header");
  2889.                         exit(1);
  2890.                     }
  2891.                     break;
  2892.       default:      message(6,"?Internal error %02x",where);
  2893.     }
  2894. }
  2895.  
  2896.  
  2897. void display_results()
  2898. {
  2899.     int i;                              /* yep, counter again... */
  2900.     int flag=0;                         /* displayed something?? */
  2901.  
  2902.     for (i=0;i<msgareas;i++)
  2903.         if (nmsgs[i])
  2904.         {
  2905.             if (!flag)
  2906.             {
  2907. #ifdef LINN
  2908.               message(2,"=     AREANAME     | MESSAGES | To Sysop | Echomail");
  2909.               message(2,"===================+==========+==========+==========");
  2910. #else
  2911.               message(2,"=     AREANAME     | MESSAGES | To Sysop");
  2912.               message(2,"===================+==========+==========");
  2913. #endif
  2914.               flag=1;
  2915.             }            
  2916. #ifdef LINN
  2917.             message(2,  "= %-16.16s |  %4d    |  %4d    |  %4d",AreaName[i],
  2918.                          nmsgs[i],smsgs[i], emsgs[i]);
  2919. #else
  2920.             message(2,  "= %-16.16s |   %3d    |   %d",AreaName[i],nmsgs[i],
  2921.                          smsgs[i]);
  2922. #endif
  2923.         }
  2924.     if (!flag) message(2,"=No mail imported");
  2925.     else message(2,"=Created %d echo-messages",echomsgs);
  2926. }
  2927.  
  2928. void process_packets()
  2929. {
  2930.     int i, na;
  2931.     
  2932.     while (open_pack())           /* open packet                */
  2933.     {
  2934.         i=1;                      /* begin this packet, so no errors (yet) */
  2935.         while ( i && read_hdr() ) /* get message header */
  2936.         {
  2937.             conv_hdr();           /* convert header */
  2938.             i=read_msg();         /* read the message */
  2939.             if (area != mailarea && ToZone[area]!=NULL)
  2940.             {
  2941.                 /* we've got echomail, so let's toss it right away */
  2942.                 getalias(ToZone[area][0],ToNet[area][0],
  2943.                                 ToNode[area][0],ToPoint[area][0]);
  2944.                 if (CheckEcho()) savemessage(LOCAL,POINTS|OTHERS|DIFFZONE);
  2945.             }
  2946.             else
  2947. #ifdef LINN
  2948.             {
  2949.                 if (killrouted & !ourmessage())
  2950.                         hhdr.flags |= KILLSEND;
  2951.                 /* import netmail to points as 4D */
  2952.                 for (na=0;na<nalias;na++)
  2953.                 {
  2954.                    if (alias[na].point && alias[na].pointnet==hhdr.Dnet &&
  2955.                    alias[na].point==hhdr.Dnode && alias[na].zone==hhdr.Dzone)
  2956.                    {
  2957.                        hhdr.Dnet=alias[na].net;
  2958.                        hhdr.Dnode=alias[na].node;
  2959.                        hhdr.Dpoint=alias[na].point;
  2960.                    }
  2961.                 }
  2962.                 savemessage(LOCAL,0);
  2963.             }
  2964. #else
  2965.                 savemessage(LOCAL,0);
  2966. #endif
  2967.         }
  2968.         if (pkt)
  2969.         {
  2970.             fclose(pkt);      /* close and */
  2971.             pkt=NULL;
  2972.         }
  2973.         if (*packet && unlink(packet))       /* delete packet */
  2974.         {
  2975.             message(6,"!Can not delete %s",packet);
  2976.             exit(2);
  2977.         }
  2978.     }
  2979. }
  2980.  
  2981. #if STTC
  2982. char *environ;
  2983.  
  2984. void main(argc, argv, envir)
  2985. int argc;
  2986. char *argv[], *envir;
  2987. #else
  2988. void main(argc, argv)
  2989. int argc;
  2990. char *argv[];
  2991. #endif
  2992. {
  2993.     int i;
  2994.     
  2995. #if STTC
  2996.     environ= envir;
  2997. #endif
  2998.  
  2999.     fprintf(stderr,
  3000.      "BERMUDA : FidoNet compatible message processing software\n");
  3001.     fprintf(stderr,
  3002.      "IMPORT utility ; Version %s created %s at %s\n\n",UVERSION,
  3003.      __DATE__,__TIME__);
  3004.     fflush(stderr);
  3005.  
  3006.     init(argc, argv);             /* initiate everything needed */
  3007.  
  3008.     message(6,"*Import mail.");
  3009.     
  3010.     process_packets();            /* first process normal mail  */
  3011.     while (process_arc())         /* process arcmail            */
  3012.     {
  3013.         process_packets();
  3014.     }
  3015.     
  3016.     if (lastarea!=-1) close_area(); /* close message files */
  3017.     display_results();
  3018.  
  3019.     for (i=0; i<10; i++) if(pktfile[i]!=NULL) ClosePacket(i);
  3020.     
  3021.  /* Get rid of all buffers (no way, let the lib take care of that part) */
  3022.  
  3023.     if (log) fclose(log);
  3024. }   /* end of program */
  3025.  
  3026.